android下的broadcast机制,注册方式有动态和静态2种注册方式。
在应用中:
静态注册(通过androidmanifest中注册)的特点是可以由系统自动注销,而动态注册(在代码中注册)的则要调用注销函数来注销。
在framework中,添加一个广播我认为也是应该有这2种方式的。不过我不知道怎么使用静态方法注册(主要原因是不知道在哪里找那个XML文件,和怎么配XML文件)。在framework中动态添加一个广播(例如在powermangerservice.java 文件中添加了一个广播),在这个广播的onreceive函数中处理了一个较耗时间的事件(网友说onreceive的生存周期是10秒左右)。我通过一个应用发送了这个广播消息,广播收到消息执行了onreceive函数,运行的情况是:耗时的事件可以处理完成,但是会有错误LOG出现;但是按照网友的说法如果在onreceive里面处理了耗时的事件可能会导致ANR(可是这里没有出现ANR),我的广播在service里面,处理了耗时的事件,出现的仅仅是说我没有调用注销函数。
E/ActivityThread(  561): Activity com.android.launcher2.Launcher has leaked IntentReceiver com.android.launcher2.Launcher$1@213519a8 that was originally registered here. Are you missing a call to unregisterReceiver()?
没有调用unregisterReceiver()函数的原因是我希望这个广播可以重复的接收消息不希望注销掉,广播注册是在powermanagerservice初始化的时候做的。我试过在onreceive()函数中调用unregisterReceiver()函数注销掉广播,这样做了后,导致这个广播无法接受下一个广播消息了。
我想知道,我这想搞一个长期接收消息的广播该怎么做才可以,不注销广播是可以长期接收但是XT报错有是为什么,该怎么解决?关于广播的onreceive函数为什么不可以处理复杂的逻辑或者耗时的任务?在framework中注册广播(2个方法)怎么操作?看网络资料说可以在onreceive()中起一个service来处理耗时的事件,所以我尝试启动了一个继承于service的服务。
由于是在framework下的powermangerservice中添加服务,首先我在base/core/res/androidmanifest.xml中添加了一个服务,在powermangerservice.java的同一个路径添加了一个服务.java文件用来启动服务使用(本来想在powermangerservice.java中直接使用内置类的方式解决的但是运行的时候总是提示找不到类)。
将耗时的事件处理放在了onstartcommand()函数里面。结果运行的时候可以处理事件,但是依然提示上面的错误LOG。
我想知道在系统启动的常驻服务里面启动一个继承于service的服务该怎么做? 
添加广播的代码
void initInThread() {
.....
filter = new IntentFilter();   
filter.addAction("fast");
mContext.registerReceiver(new FastPoweroffBroadcastReceiver(), filter);
....
}
private final class FastPoweroffBroadcastReceiver extends BroadcastReceiver {                                                                          
          @Override
          public void onReceive(Context context, Intent intent) {
              String action = intent.getAction();
              Log.e(TAG,"you press no" + action);
              Intent mIntent = new Intent(context, FastPoweroffService.class);
              mIntent.putExtras(intent);
              mIntent.putExtra("action", intent.getAction());
              context.startService(mIntent);
              //处理耗时的任务 (不开启服务的时候)
              //开启服务就在服务里面处理
              Log.e(TAG,"onReceive is over");
          }
}在AndroidManifest.xml文件中添加一下代码位置在 application包含的范围里面
<service android:name="com.android.server.FastPoweroffService"
             android:permission=""
             android:enabled="true"/>
package com.android.server;                                                                                                                                 
  
   import android.app.Service;
   import android.os.Binder;
   import android.os.IBinder;
   import android.content.Intent;
   import android.content.Context;
   import android.util.Log;
   import com.android.server.pm.ShutdownThread;
  import android.os.PowerManager;
  import android.os.Handler;
  import android.os.HandlerThread;
  import android.os.Message;
  import android.os.Looper;
  
  public class FastPoweroffService extends Service {
      private static final String TAG = "___>>FastPowerService";
      private Context mContext;
      public FastPoweroffService() {..
          super();
          // TODO Auto-generated constructor stub..
      }
      
      @Override
      public IBinder onBind(Intent intent) {
          return null;
      }
      @Override
      public void onCreate() {
          super.onCreate();
          mContext = this;
          Log.v(TAG, "onCreate=================n=");
      }
      @Override
      public int onStartCommand(Intent intent, int flags, int startId) {
         if(intent != null){
             Log.v(TAG, "onStartCommand=================n=");
             //耗时任务的处理在这里
             stopSelf(startId);
         }
         stopSelf(startId);
         return START_REDELIVER_INTENT;
     }     @Override
     public void onDestroy() {
         Log.v(TAG, "onDestroy==================");
         super.onDestroy();
     }
 }androidbroadcast androidbroadcastservice

解决方案 »

  1.   

    一下是onreceive()处理耗时任务的出现的错误LOG;如果将同样的任务放在service里面处理会出现一遍错误LOG,并且2种情况下任务都可以跑完.
    11-14 00:05:14.849 E/jdwp    ( 4628): Failed sending reply to debugger: Broken pipe
    11-14 00:05:14.859 D/dalvikvm( 4628): Debugger has detached; object registry had 1 entries
    11-14 00:05:14.919 E/ActivityThread(  561): Activity com.android.launcher2.Launcher has leaked IntentReceiver com.android.launcher2.Launcher$1@213519a8 that was originally registered here. Are you missing a call to unregisterReceiver()?
    11-14 00:05:14.919 E/ActivityThread(  561): android.app.IntentReceiverLeaked: Activity com.android.launcher2.Launcher has leaked IntentReceiver com.android.launcher2.Launcher$1@213519a8 that was originally registered here. Are you missing a call to unregisterReceiver()?
    11-14 00:05:14.919 E/ActivityThread(  561):  at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:792)
    11-14 00:05:14.919 E/ActivityThread(  561):  at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:593)
    11-14 00:05:14.919 E/ActivityThread(  561):  at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1111)
    11-14 00:05:14.919 E/ActivityThread(  561):  at android.app.ContextImpl.registerReceiver(ContextImpl.java:1098)
    11-14 00:05:14.919 E/ActivityThread(  561):  at android.app.ContextImpl.registerReceiver(ContextImpl.java:1092)
    11-14 00:05:14.919 E/ActivityThread(  561):  at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:365)
    11-14 00:05:14.919 E/ActivityThread(  561):  at com.android.launcher2.Launcher.onCreate(Launcher.java:439)
    11-14 00:05:14.919 E/ActivityThread(  561):  at android.app.Activity.performCreate(Activity.java:5008)
    11-14 00:05:14.919 E/ActivityThread(  561):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
    11-14 00:05:14.919 E/ActivityThread(  561):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
    11-14 00:05:14.919 E/ActivityThread(  561):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
    11-14 00:05:14.919 E/ActivityThread(  561):  at android.app.ActivityThread.access$600(ActivityThread.java:130)
    11-14 00:05:14.919 E/ActivityThread(  561):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
    11-14 00:05:14.919 E/ActivityThread(  561):  at android.os.Handler.dispatchMessage(Handler.java:99)
    11-14 00:05:14.919 E/ActivityThread(  561):  at android.os.Looper.loop(Looper.java:137)
    11-14 00:05:14.919 E/ActivityThread(  561):  at android.app.ActivityThread.main(ActivityThread.java:4745)
    11-14 00:05:14.919 E/ActivityThread(  561):  at java.lang.reflect.Method.invokeNative(Native Method)
    11-14 00:05:14.919 E/ActivityThread(  561):  at java.lang.reflect.Method.invoke(Method.java:511)
    11-14 00:05:14.919 E/ActivityThread(  561):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
    11-14 00:05:14.919 E/ActivityThread(  561):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    11-14 00:05:14.919 E/ActivityThread(  561):  at dalvik.system.NativeStart.main(Native Method)
    11-14 00:05:14.929 E/StrictMode(  561): null
    11-14 00:05:14.929 E/StrictMode(  561): android.app.IntentReceiverLeaked: Activity com.android.launcher2.Launcher has leaked IntentReceiver com.android.launcher2.Launcher$1@213519a8 that was originally registered here. Are you missing a call to unregisterReceiver()?
    11-14 00:05:14.929 E/StrictMode(  561):  at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:792)
    11-14 00:05:14.929 E/StrictMode(  561):  at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:593)
    11-14 00:05:14.929 E/StrictMode(  561):  at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1111)
    11-14 00:05:14.929 E/StrictMode(  561):  at android.app.ContextImpl.registerReceiver(ContextImpl.java:1098)
    11-14 00:05:14.929 E/StrictMode(  561):  at android.app.ContextImpl.registerReceiver(ContextImpl.java:1092)
    11-14 00:05:14.929 E/StrictMode(  561):  at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:365)
    11-14 00:05:14.929 E/StrictMode(  561):  at com.android.launcher2.Launcher.onCreate(Launcher.java:439)
    11-14 00:05:14.929 E/StrictMode(  561):  at android.app.Activity.performCreate(Activity.java:5008)
    11-14 00:05:14.929 E/StrictMode(  561):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
    11-14 00:05:14.929 E/StrictMode(  561):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
    11-14 00:05:14.929 E/StrictMode(  561):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
    11-14 00:05:14.929 E/StrictMode(  561):  at android.app.ActivityThread.access$600(ActivityThread.java:130)
    11-14 00:05:14.929 E/StrictMode(  561):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
    11-14 00:05:14.929 E/StrictMode(  561):  at android.os.Handler.dispatchMessage(Handler.java:99)
    11-14 00:05:14.929 E/StrictMode(  561):  at android.os.Looper.loop(Looper.java:137)
    11-14 00:05:14.929 E/StrictMode(  561):  at android.app.ActivityThread.main(ActivityThread.java:4745)
    11-14 00:05:14.929 E/StrictMode(  561):  at java.lang.reflect.Method.invokeNative(Native Method)
    11-14 00:05:14.929 E/StrictMode(  561):  at java.lang.reflect.Method.invoke(Method.java:511)
    11-14 00:05:14.929 E/StrictMode(  561):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
    11-14 00:05:14.929 E/StrictMode(  561):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    11-14 00:05:14.929 E/StrictMode(  561):  at dalvik.system.NativeStart.main(Native Method)
      

  2.   

    11-14 00:05:14.979 E/ActivityThread(  561): Activity com.android.launcher2.Launcher has leaked IntentReceiver com.android.launcher2.Launcher$1@2144fa98 that was originally registered here. Are you missing a call to unregisterReceiver()?
    11-14 00:05:14.979 E/ActivityThread(  561): android.app.IntentReceiverLeaked: Activity com.android.launcher2.Launcher has leaked IntentReceiver com.android.launcher2.Launcher$1@2144fa98 that was originally registered here. Are you missing a call to unregisterReceiver()?
    11-14 00:05:14.979 E/ActivityThread(  561):  at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:792)
    11-14 00:05:14.979 E/ActivityThread(  561):  at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:593)
    11-14 00:05:14.979 E/ActivityThread(  561):  at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1111)
    11-14 00:05:14.979 E/ActivityThread(  561):  at android.app.ContextImpl.registerReceiver(ContextImpl.java:1098)
    11-14 00:05:14.979 E/ActivityThread(  561):  at android.app.ContextImpl.registerReceiver(ContextImpl.java:1092)
    11-14 00:05:14.979 E/ActivityThread(  561):  at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:365)
    11-14 00:05:14.979 E/ActivityThread(  561):  at com.android.launcher2.Launcher.onCreate(Launcher.java:439)
    11-14 00:05:14.979 E/ActivityThread(  561):  at android.app.Activity.performCreate(Activity.java:5008)
    11-14 00:05:14.979 E/ActivityThread(  561):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
    11-14 00:05:14.979 E/ActivityThread(  561):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
    11-14 00:05:14.979 E/ActivityThread(  561):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
    11-14 00:05:14.979 E/ActivityThread(  561):  at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3512)
    11-14 00:05:14.979 E/ActivityThread(  561):  at android.app.ActivityThread.access$700(ActivityThread.java:130)
    11-14 00:05:14.979 E/ActivityThread(  561):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1201)
    11-14 00:05:14.979 E/ActivityThread(  561):  at android.os.Handler.dispatchMessage(Handler.java:99)
    11-14 00:05:14.979 E/ActivityThread(  561):  at android.os.Looper.loop(Looper.java:137)
    11-14 00:05:14.979 E/ActivityThread(  561):  at android.app.ActivityThread.main(ActivityThread.java:4745)
    11-14 00:05:14.979 E/ActivityThread(  561):  at java.lang.reflect.Method.invokeNative(Native Method)
    11-14 00:05:14.979 E/ActivityThread(  561):  at java.lang.reflect.Method.invoke(Method.java:511)
    11-14 00:05:14.979 E/ActivityThread(  561):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
    11-14 00:05:14.979 E/ActivityThread(  561):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    11-14 00:05:14.979 E/ActivityThread(  561):  at dalvik.system.NativeStart.main(Native Method)
    11-14 00:05:14.989 E/StrictMode(  561): null
    11-14 00:05:14.989 E/StrictMode(  561): android.app.IntentReceiverLeaked: Activity com.android.launcher2.Launcher has leaked IntentReceiver com.android.launcher2.Launcher$1@2144fa98 that was originally registered here. Are you missing a call to unregisterReceiver()?
    11-14 00:05:14.989 E/StrictMode(  561):  at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:792)
    11-14 00:05:14.989 E/StrictMode(  561):  at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:593)
    11-14 00:05:14.989 E/StrictMode(  561):  at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1111)
    11-14 00:05:14.989 E/StrictMode(  561):  at android.app.ContextImpl.registerReceiver(ContextImpl.java:1098)
    11-14 00:05:14.989 E/StrictMode(  561):  at android.app.ContextImpl.registerReceiver(ContextImpl.java:1092)
    11-14 00:05:14.989 E/StrictMode(  561):  at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:365)
    11-14 00:05:14.989 E/StrictMode(  561):  at com.android.launcher2.Launcher.onCreate(Launcher.java:439)
    11-14 00:05:14.989 E/StrictMode(  561):  at android.app.Activity.performCreate(Activity.java:5008)
    11-14 00:05:14.989 E/StrictMode(  561):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
    11-14 00:05:14.989 E/StrictMode(  561):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
    11-14 00:05:14.989 E/StrictMode(  561):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
    11-14 00:05:14.989 E/StrictMode(  561):  at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3512)
    11-14 00:05:14.989 E/StrictMode(  561):  at android.app.ActivityThread.access$700(ActivityThread.java:130)
    11-14 00:05:14.989 E/StrictMode(  561):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1201)
    11-14 00:05:14.989 E/StrictMode(  561):  at android.os.Handler.dispatchMessage(Handler.java:99)
    11-14 00:05:14.989 E/StrictMode(  561):  at android.os.Looper.loop(Looper.java:137)
    11-14 00:05:14.989 E/StrictMode(  561):  at android.app.ActivityThread.main(ActivityThread.java:4745)
    11-14 00:05:14.989 E/StrictMode(  561):  at java.lang.reflect.Method.invokeNative(Native Method)
    11-14 00:05:14.989 E/StrictMode(  561):  at java.lang.reflect.Method.invoke(Method.java:511)
    11-14 00:05:14.989 E/StrictMode(  561):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
    11-14 00:05:14.989 E/StrictMode(  561):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    11-14 00:05:14.989 E/StrictMode(  561):  at dalvik.system.NativeStart.main(Native Method)
    11-14 00:05:15.039 I/WAKELOCK_RELEASE(  339): TIMESTAMP=156052015029, TAG=SCREEN_FROZEN, TYPE=PARTIAL_WAKE_LOCK, COUNT=1, PID=339, UID=1000
      

  3.   

    用receiver接收到广播后,启动一个service在后台处理,虽然Service没有UI线程,但耗时操作还是不要放在住线程里面,比如onstartcommand()方法,你应该起一个线程来处理耗时操作。