Android Activity接收Service傳送的廣播
阿新 • • 發佈:2019-01-24
最近接觸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 blocke.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); } }