Android开关机源码分析

2.1Android关机流程
   Android关机流程的介绍网上很多,现在摘抄一段如下:

点击(此处)折叠或打开

  1. 关机动作从按键触发中断,linux kernel层给android framework层返回按键事件进入 framework层,再从 framework层到kernel层执行kernel层关机任务。

  2. 长按键对应的handler代码:

  3. frameworks/policies/base/phone/com/android/internal/policy/impl/PhoneWindowManager.java
  4. Runnable mPowerLongPress;

  5. private final Runnable mPowerLongPress = new Runnable() {
  6. public void run() {
  7. if (!mPowerKeyHandled) {
  8. mPowerKeyHandled = true;
  9. performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
  10. sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
  11. showGlobalActionsDialog();
  12. }
  13. }
  14. };

  15. mPowerLongPress 启动关机对话框

  16. (frameworks/policies/base/phone/com/android/internal/policy/impl/GlobalActions.java)

  17. 如果我们选择Power OFF’,会调用 ShutdownThread.shutdown. 启动关机线程执行关机动作

  18. frameworks/base/core/java/com/android/internal/app/ShutdownThread.java

  19. 真正关机 流程:

  20. (1)广播全局事件, ACTION_SHUTDOWN Intent

  21. (2)shutdown ActivityManager 服务

  22. (3) 停止蓝牙服务

  23. (4) 停止 电话服务 (radio phone service)

  24. (5)停止mount 服务

  25. (6) 调用 Power.shutdown() 进入native 层

  26. frameworks/base/core/java/android/os/Power.java

  27. power的native实现代码:

  28. frameworks/base/core/jni/android_os_Power.cpp

  29. static void android_os_Power_shutdown(JNIEnv *env, jobject clazz)
  30. {
  31. sync();
  32. #ifdef HAVE_ANDROID_OS
  33. reboot(RB_POWER_OFF);
  34. #endif
  35. }

  36. sync, reboot 为linux系统调用,进入linux内核关机流程。

  37. 完毕。
仔细按照上面说的流程跟下去,确实是这样的,只不过根据产品的不同,会有一定的修改,例如产品是平板电脑,就会比手机少很多废话对话框,如果是智能电视,则又会有不同对于这个任务来说,比较重要的ShutdownThread.java这个文件,这个文件启动了关机的对话框,关机对话框效果如图:

PhoneWindowManager中调用ShutdownThread的代码如下:

点击(此处)折叠或打开

  1. mPowerKeyHandled = true;
  2. performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
  3. sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
  4. ShutdownThread.shutdown(mContext, true);
传入第一个参数不解释,第二个参数是是否显示对话框,true就是显示

2.2应用中关机的方法

  凭借网络这个好老师,我找到了好几种实现关机的方法,一是通过向控制台写shutdown命令完成,Android是建立在Linux基础上的,所以这种方法需要Root。
  二是启动ShutdownThread中的对话框,PhoneWindowManager直接通过一句
ShutdownThread.shutdown(mContext, true); 就启动了,后面我也试过这种方法,确实可以启动,但是点击确定却一直关不了机。所以靠谱的方法还是通过Intent启动。方法如下

点击(此处)折叠或打开

  1. Intent shutdown = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
  2. shutdown.putExtra(Intent.EXTRA_KEY_CONFIRM, true);
  3. shutdown.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
  4. startActivity(shutdown);
   这上面的一些Flag值AndroidSDK中并没有公开,所以工程要放在Android源码中才能编译通过,除此之外还需要设置系统权限,需要通过修改AndroidManfast.xml文件实现。

2.3Appwidget的框架
  
个人感觉AppWidget像是嵌入launcher中的View,和AppWidget本身Activity的不是运行在同一个进程中,所以控制Appwidget都需要用RemoteViews控制。
    桌面上有多个不同的AppWidget,如何得知哪一个被激活呢,这主要通过广播完成,广播发出的是在AndroidManfast.xml中定义好的android:name,接收时需要在OnReceive()方法中进行判断。
    AndroidMainfast.xml摘录如下:

点击(此处)折叠或打开

  1. <receiver android:name="AppWidget">
  2.             <intent-filter>
  3.             <action
  4.                 android:name="android.appwidget.action.APPWIDGET_UPDATE">
  5.             </action>
  6.             </intent-filter>
  7.                 <meta-data android:name="android.appwidget.provider"
  8.                             android:resource="@xml/appwidget01" />
  9.              <intent-filter>
  10.                 <action android:name="com.android.shutdownapp"></action>
  11.             </intent-filter>
  12. </receiver>
   Appwidget的处理片段如下:

点击(此处)折叠或打开

  1. @Override
  2.     public void onReceive(Context context, Intent intent)
  3.     {
  4.         if (intent.getAction().equals(broadCastString))
  5.         {                
  6.             RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.appwidgetlayout);
  7.             remoteViews.setTextViewText(R.id.btnSend, "shutdown");    
  8.             AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
  9.             ComponentName componentName = new ComponentName(context,AppWidget.class);
  10.             appWidgetManager.updateAppWidget(componentName, remoteViews);
  11.         }
  12.         super.onReceive(context, intent);
  13.     }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值