我試圖創建一個簡單的程序,執行以下操作:使用服務,TimerTask的和廣播接收器來檢查各種更新
- 我的活動啓動的服務(NewsService)(UpdateServiceActivity)檢查的消息。
- 如果發現新聞(NewsService)向接收器(NewsReceiver)發送廣播。
- 收到廣播後,接收方(NewsReceiver)應通知活動(UpdateServiceActivity)有新聞。
- 通知後,活動(UpdateServiceActivity)獲取新聞並處理它們。
到目前爲止,我只是一個簡單的例子。這是我到目前爲止的代碼:
UpdateServiceActivity
public class UpdateServiceActivity extends Activity implements OnClickListener {
private static final String TAG = "UpdateServiceActivity";
Button buttonStart, buttonStop;
BroadcastReceiver receiver;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
buttonStart = (Button) findViewById(R.id.buttonStart);
buttonStop = (Button) findViewById(R.id.buttonStop);
buttonStart.setOnClickListener(this);
buttonStop.setOnClickListener(this);
receiver = new NewsReceiver();
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
@Override
protected void onResume() {
super.onResume();
registerReceiver(receiver, new IntentFilter());
}
public void onClick(View src) {
switch(src.getId()) {
case R.id.buttonStart:
Log.e(TAG, "onClick: starting service");
startService(new Intent(this, NewsService.class));
break;
case R.id.buttonStop:
Log.e(TAG, "onClick: stopping service");
stopService(new Intent(this, NewsService.class));
break;
}
}
}
NewsService
public class NewsService extends Service {
public static final String NEWS_INTENT = "bs.kalender.news";
private Timer timer = new Timer();
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onStart(Intent intent, int startId) {
startService();
}
private void startService() {
timer.scheduleAtFixedRate(new NewsChecker(), 0, 5000);
}
private class NewsChecker extends TimerTask {
@Override
public void run() {
Intent intent = new Intent(getApplicationContext(), NewsReceiver.class);
sendBroadcast(intent);
}
}
}
NewsReceiver
public class NewsReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Broadcast recieved! There is news!", Toast.LENGTH_SHORT).show();
}
}
個清單
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="bs.update"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="7" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
<activity android:name=".UpdateServiceActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".NewsService" />
<receiver android:name=".NewsReceiver" />
</application>
</manifest>
我運行的問題是:
- 當擊中「Home'按鈕(在App轉到後臺,並且暫停被調用)的NewsReceiver保持發射吐司。我的理解是,一旦我註銷接收者,就不應該接收廣播。
- 即使我點擊按鈕來停止NewsService,TimerTask仍會繼續運行併發布廣播。
我在做什麼錯?這是對廣播/接收如何工作的普遍誤解嗎?我的軌道上,應該改變什麼來完成我的願望?
這將在UI線程上運行,因此如果您必須執行實際的網絡I/O,則會出現問題。如果你只需要這個工作,而應用程序可見,你可以看看'AsyncTask'或啓動一個處理線程。 –
您能否提供一個提供相同功能的示例實現?我考慮過使用AsynTask,但我發現這樣做並不適合Android框架(安排特定任務以給定間隔運行,然後應該在UI上發佈結果)。 AsyncTask適合一次性執行,但只要我的Activity可見,我就需要它運行(例如,任務在onPause中停止並在onResume中重新啓動)。 – kaspermoerch
您可以使用ScheduledThreadPoolExecutor定期運行'NewsHandler'並將消息發佈到'NewsEventHandler'來更新UI(您不需要'postDelayed()',但是您需要啓動/停止執行程序暫停/恢復)。或者,如果要使用處理程序執行此操作,請使用類似於'HandlerThread thread = new HandlerThread(「HT」)的後臺線程運行它。 Handler handlerTimer = new Handler(thread.getLooper());' –