zoukankan      html  css  js  c++  java
  • Android Activity接收Service发送的广播

      最近接触Android,有很多不明白的地方,也走了很多弯路,现在将我今天走的弯路贴上来,也为了避免初学者也走这种弯路。

      Android中Activity接收广播的方式是建一个内部类,该内部类继承BroadcastReceiver类,而Service端在完成一个耗时操作后,可以发送广播用来通知别的组件完成任务了,这样就实现了Service与Activity的通信,Service的代码比较简单,如下所示

    public class PassengerService extends Service {
        private ThreadGroup myThreads = new ThreadGroup("ServiceWorker");//用ThreadGroup类而不是Thread类,因为Service中可能有多个耗时的子线程
    
        @Override
        public void onCreate() {
            // TODO Auto-generated method stub
            super.onCreate();
            new Thread(myThreads, new DownLoadAd(), "background").start();//Service已启动,就开始子线程
        }
    
        @Override
        public IBinder onBind(Intent arg0) {
            // TODO Auto-generated method stub
            return null;
        }
    
        //Service中要实现的线程,以休眠5秒表示一个耗时操作
        class DownLoadAd implements Runnable {
            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                Intent intent = new Intent();
                intent.setAction("polly.liu.Image");//用隐式意图来启动广播
                intent.putExtra("msg", "图片下载好了");
                sendBroadcast(intent);
            }
        }
    }

    这一步比较简单,基本上不会有什么疑问。我自己在做Activity端的接收程序时,遇到了几点问题,下面一一呈现:

      我最初的代码如下:

      Activity:

      

    public class LoginActivity extends Activity{
        BroadcastMain receiver;
        //内部类,实现BroadcastReceiver
        public class BroadcastMain extends BroadcastReceiver{
            //必须要重载的方法,用来监听是否有广播发送
            @Override
            public void onReceive(Context context, Intent intent) {
                Toast.makeText(LoginActivity.this, intent.getStringExtra("msg"), 1).show();        
            }
        }    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            requestWindowFeature(Window.FEATURE_NO_TITLE);
            setContentView(R.layout.login);
            receiver = new BroadcastMain();
        }
    }

      然后AndroidManifest中添加了

    <receiver android:name="polly.liu.LoginActivity.BroadcastMain">
                <intent-filter>
                    <action android:name="polly.liu.Image"/>
                </intent-filter>
    </receiver>

      程序运行,出错,报错原因大概是不能实例化polly.liu.LoginActivity.BroadcastMain这个类,于是我好像明白了在AndroidManifest不能添加内部类,于是寻找在代码中注册BroadcastMain这个广播接收类的方法,于是代码改变如下:

    public class LoginActivity extends Activity{
        BroadcastMain receiver;
        //内部类,实现BroadcastReceiver
        public class BroadcastMain extends BroadcastReceiver{
            //必须要重载的方法,用来监听是否有广播发送
            @Override
            public void onReceive(Context context, Intent intent) {
                Toast.makeText(LoginActivity.this, intent.getStringExtra("msg"), 1).show();        
            }
        }    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            requestWindowFeature(Window.FEATURE_NO_TITLE);
            setContentView(R.layout.login);
            receiver = new BroadcastMain();
            //新添代码,在代码中注册广播接收程序
            IntentFilter filter = new IntentFilter();
            filter.addAction("polly.liu.Image");
            registerReceiver(receiver, filter);
        }
    }

      一运行,没报错,并且程序运行5秒以后,弹出了Toast,“图片下载成功”,有点沾沾自喜,但是关闭程序,第二次再启动程序以后,并未弹出“图片下载成功”,翻来覆去找原因,未果,但是,一个手贱,用腾讯手机助手将所有无关进程关闭以后,再重新运行程序,又弹出“图片下载成功”的提示了,于是觉得是Service生命周期的原因,果断修改代码:

     

    public class LoginActivity extends Activity{
        BroadcastMain receiver;
        //内部类,实现BroadcastReceiver
        public class BroadcastMain extends BroadcastReceiver{
            //必须要重载的方法,用来监听是否有广播发送
            @Override
            public void onReceive(Context context, Intent intent) {
                Toast.makeText(LoginActivity.this, intent.getStringExtra("msg"), 1).show();    
            }
        }    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            requestWindowFeature(Window.FEATURE_NO_TITLE);
            setContentView(R.layout.login);
            receiver = new BroadcastMain();
            //新添代码,在代码中注册广播接收程序
            IntentFilter filter = new IntentFilter();
            filter.addAction("polly.liu.Image");
            registerReceiver(receiver, filter);
        }
        @Override
        protected void onDestroy() {
            // TODO Auto-generated method stub
            super.onDestroy();
            Intent intent = new Intent();
            intent.setClass(this, PassengerService.class);
            stopService(intent);
        }
    }

    大功告成!

  • 相关阅读:
    Oracle学习系列7
    oracle 体系结构
    数据库设计三大范式
    Oracle学习系列6
    Oracle学习系列5
    Unity3D for Android 纹理压缩支持
    Unity项目UI图片压缩格式(UGUI)
    [Unity3D]关于U3D贴图格式压缩
    unity 联机调试(android ios)
    UGUI 文字效果实现(ShadowGradientOutline)
  • 原文地址:https://www.cnblogs.com/liubo68/p/2997132.html
Copyright © 2011-2022 走看看