Android 长按电源键关机整个流程小学习

简介: Android 长按电源键关机整个流程小学习            最近研究了一下android关机跟重新启动功能,看了一些长按电源键到弹出关机对话框,到真正关机的一系列处理过程。

Android 长按电源键关机整个流程小学习

 

           最近研究了一下android关机跟重新启动功能,看了一些长按电源键到弹出关机对话框,到真正关机的一系列处理过程。

首先还是来看看这个长按电源键都干了些什么吧?一般来说,电源键都是接到PMU上的,PMU来判断是长按还短按,当有按键消息产生的时候,系统会有中断,然后去读PMU的状态就可以知道是什么了。笔者以全志平台的AXP209小议一下,先贴上关键代码:

static int axp_battery_event(struct notifier_block *nb, unsigned long event,
        void *data)
{
	struct axp_charger *charger =
	container_of(nb, struct axp_charger, nb);
    uint8_t w[9];
	w[0] = (uint8_t) ((event) & 0xFF);
	w[1] = POWER20_INTSTS2;
	w[2] = (uint8_t) ((event >> 8) & 0xFF);
	w[3] = POWER20_INTSTS3;
	w[4] = (uint8_t) ((event >> 16) & 0xFF);
	w[5] = POWER20_INTSTS4;
	w[6] = (uint8_t) ((event >> 24) & 0xFF);
	w[7] = POWER20_INTSTS5;
	w[8] = (uint8_t) (((uint64_t) event >> 32) & 0xFF);

	if(event & (AXP20_IRQ_BATIN|AXP20_IRQ_BATRE)) {
		axp_capchange(charger);
	}

	if(event & (AXP20_IRQ_ACIN|AXP20_IRQ_USBIN|AXP20_IRQ_ACOV|AXP20_IRQ_USBOV|AXP20_IRQ_CHAOV
				|AXP20_IRQ_CHAST|AXP20_IRQ_TEMOV|AXP20_IRQ_TEMLO)) {
		axp_change(charger);
	}

	if(event & (AXP20_IRQ_ACRE|AXP20_IRQ_USBRE)) {
		axp_change(charger);
	}

	if(event & AXP20_IRQ_PEKLO) {
		axp_presslong(charger);
	}

	if(event & AXP20_IRQ_PEKSH) {
		axp_pressshort(charger);
	}

	DBG_PSY_MSG("event = 0x%x\n",(int) event);
	axp_writes(charger->master,POWER20_INTSTS1,9,w);

	return 0;
}

短按跟长按具体也就是上报的延时区别,如下:

static void axp_presslong(struct axp_charger *charger)
{
	DBG_PSY_MSG("press long\n");
	input_report_key(powerkeydev, KEY_POWER, 1);
	input_sync(powerkeydev);
	ssleep(2);
	DBG_PSY_MSG("press long up\n");
	input_report_key(powerkeydev, KEY_POWER, 0);
	input_sync(powerkeydev);
}

static void axp_pressshort(struct axp_charger *charger)
{
	DBG_PSY_MSG("press short\n");
	input_report_key(powerkeydev, KEY_POWER, 1);
	input_sync(powerkeydev);
	msleep(100);
	input_report_key(powerkeydev, KEY_POWER, 0);
	input_sync(powerkeydev);
}

     在inputmanager里面再解析出是长按还是短按,来做相应处理。如果是长按,就弹出对话框,在弹出对话框之前,有几次传递,还是activitymanger跟Windowsmanagerservice做宏观调控,最终把消息传到苦逼的ShutdownThread,不过ShutdownThread也不难弄。/*****************************************************************************************************/
声明:本博内容均由http://blog.csdn.net/sundesheng125原创,转载请注明出处,谢谢!
/*****************************************************************************************************/

 首先来看一下,在ShutdownThread里面有一个CloseDialogReceiver来关注Intent.ACTION_CLOSE_SYSTEM_DIALOGS,它收到这个消息就会关闭这个对话框。对话框怎么起来的呢?请看下面的源码:

 

        if (confirm) {
            final CloseDialogReceiver closer = new CloseDialogReceiver(context);
            final AlertDialog dialog = new AlertDialog.Builder(context)
                    .setTitle(com.android.internal.R.string.power_off)
                    .setMessage(resourceId)
                    .setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            beginShutdownSequence(context);
                        }
                    })
                    .setNegativeButton(com.android.internal.R.string.no, null)
                    .create();
            closer.dialog = dialog;
            dialog.setOnDismissListener(closer);
            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
            dialog.show();
        } else {
            beginShutdownSequence(context);
        }

    其实就是一个AlertDialog,也没什么新鲜的,只是在setPositiveButton的时候注册了clicklistener来监听你是否按下了,按下了就直接执行beginShutdownSequence。在beginShutdownSequence还会弹出一个进度的对话框,代码如下:

        ProgressDialog pd = new ProgressDialog(context);
        pd.setTitle(context.getText(com.android.internal.R.string.power_off));
        pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));
        pd.setIndeterminate(true);
        pd.setCancelable(false);
        pd.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);

        pd.show();

      在里面还会调用两个非常重要的Power.shutdown()跟Power.reboot(reason),看你是重启还是关机了。

    /**
     * Low-level function turn the device off immediately, without trying
     * to be clean.  Most people should use
     * {@link android.internal.app.ShutdownThread} for a clean shutdown.
     *
     * @deprecated
     * @hide
     */
    @Deprecated
    public static native void shutdown();

    /**
     * Reboot the device.
     * @param reason code to pass to the kernel (e.g. "recovery"), or null.
     *
     * @throws IOException if reboot fails for some reason (eg, lack of
     *         permission)
     */
    public static void reboot(String reason) throws IOException
    {
        rebootNative(reason);
    }

    private static native void rebootNative(String reason) throws IOException ;

      再往下跟,

static void android_os_Power_shutdown(JNIEnv *env, jobject clazz)
{
    android_reboot(ANDROID_RB_POWEROFF, 0, 0);
}

extern int go_recovery(void);

static void android_os_Power_reboot(JNIEnv *env, jobject clazz, jstring reason)
{
    if (reason == NULL) {
        android_reboot(ANDROID_RB_RESTART, 0, 0);
    } else {
        const char *chars = env->GetStringUTFChars(reason, NULL);
        //android_reboot(ANDROID_RB_RESTART2, 0, (char *) chars);
        go_recovery();
        android_reboot(ANDROID_RB_RESTART, 0, 0);
        env->ReleaseStringUTFChars(reason, chars);  // In case it fails.
    }
    jniThrowIOException(env, errno);
}

 所以,整个流程都是好的,学习理了一下流程,大部分都是源码,把它搞清楚也是有好处的。



目录
相关文章
|
18天前
|
Android开发
Android学习 —— 测试init.rc中的条件触发的处理顺序
Android学习 —— 测试init.rc中的条件触发的处理顺序
|
24天前
|
Android开发
我的Android进阶修炼:安卓启动流程之init(1)
本文深入分析了Android系统中的init进程,包括其源码结构、主要功能以及启动流程的详细注解,旨在帮助读者理解init作为用户空间的1号进程在Android启动过程中的关键作用。
25 1
|
24天前
|
搜索推荐 Android开发
学习AOSP安卓系统源代码,需要什么样的电脑?不同配置的电脑,其编译时间有多大差距?
本文分享了不同价位电脑配置对于编译AOSP安卓系统源代码的影响,提供了从6000元到更高价位的电脑配置实例,并比较了它们的编译时间,以供学习AOSP源代码时电脑配置选择的参考。
44 0
学习AOSP安卓系统源代码,需要什么样的电脑?不同配置的电脑,其编译时间有多大差距?
|
1月前
|
XML 前端开发 Android开发
Android面试高频知识点(3) 详解Android View的绘制流程
View的绘制和事件处理是两个重要的主题,上一篇《图解 Android事件分发机制》已经把事件的分发机制讲得比较详细了,这一篇是针对View的绘制,View的绘制如果你有所了解,基本分为measure、layout、draw 过程,其中比较难理解就是measure过程,所以本篇文章大幅笔地分析measure过程,相对讲得比较详细,文章也比较长,如果你对View的绘制还不是很懂,对measure过程掌握得不是很深刻,那么耐心点,看完这篇文章,相信你会有所收获的。
69 2
|
2月前
|
Java Android开发
android 设置系统时间的流程
android 设置系统时间的方法
227 2
|
3月前
|
ARouter IDE 开发工具
Android面试题之App的启动流程和启动速度优化
App启动流程概括: 当用户点击App图标,Launcher通过Binder IPC请求system_server启动Activity。system_server指示Zygote fork新进程,接着App进程向system_server申请启动Activity。经过Binder通信,Activity创建并回调生命周期方法。启动状态分为冷启动、温启动和热启动,其中冷启动耗时最长。优化技巧包括异步初始化、避免主线程I/O、类加载优化和简化布局。
58 3
Android面试题之App的启动流程和启动速度优化
|
3月前
|
安全 网络协议 算法
Android网络基础面试题之HTTPS的工作流程和原理
HTTPS简述 HTTPS基于TCP 443端口,通过CA证书确保服务器身份,使用DH算法协商对称密钥进行加密通信。流程包括TCP握手、证书验证(公钥解密,哈希对比)和数据加密传输(随机数加密,预主密钥,对称加密)。特点是安全但慢,易受特定攻击,且依赖可信的CA。每次请求可能复用Session ID以减少握手。
48 2
|
2月前
|
消息中间件 前端开发 Android开发
Android面试题自定义View之Window、ViewRootImpl和View的三大流程
Android开发中,View的三大核心流程包括measure(测量)、layout(布局)和draw(绘制)。MeasureSpec类在测量过程中起到关键作用,它结合尺寸大小和模式(EXACTLY、AT_MOST、UNSPECIFIED)来指定View应如何测量。onMeasure方法用于自定义View的测量,布局阶段,ViewGroup调用onLayout确定子元素位置,而draw阶段按照特定顺序绘制背景、内容、子元素和装饰。整个流程始于ViewRootImpl的performTraversals,该方法触发测量、布局和绘制。
36 0
|
3月前
|
Android开发
Android面试题之activity启动流程
该文探讨了Android应用启动和Activity管理服务(AMS)的工作原理。从Launcher启动应用开始,涉及Binder机制、AMS回调、进程创建、Application和Activity的生命周期。文中详细阐述了AMS处理流程,包括创建ClassLoader、加载APK、启动Activity的步骤,以及权限校验和启动模式判断。此外,还补充了activity启动流程中AMS的部分细节。欲了解更多内容,可关注公众号“AntDream”。
36 1
|
3月前
|
存储 XML 数据库
深入地了解Android应用开发的流程和技术
深入地了解Android应用开发的流程和技术
26 0