我正在尝试创建一个执行以下操作的简单程序:
到目前为止,我只是在研究一个简单的例子。到目前为止,这是我的代码:
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>
我遇到的问题是:
我做错了什么?广播/接收的工作方式是否普遍存在误解?我是否正在走上正轨,应该改变什么以实现我的目标?
答案 0 :(得分:5)
Receiver
实例,但这对您在清单文件中注册的接收方没有任何影响。尝试从清单中删除它。 Timer
这就是它继续射击的原因。停止服务不会自动停止您创建的线程(例如Timer
使用的线程)通常,您应该使用AlarmManager
和IntentService
来安排重复的后台任务。 Timer
不可靠,与Android框架不太匹配。此外,如果手机处于睡眠状态,则Timer
将无法执行。您可以通过AlarmManager
唤醒手机以执行警报(对于新闻更新服务而言,这是另一个问题)。
答案 1 :(得分:1)
修改强>
这与Nikolay Elenkov关于使用ScheduledThreadPoolExecutor的建议相结合提供了一个非常好的解决方案。
我找到的解决方案比使用Service和BroadcastReceiver更符合我的目的。当应用程序未运行时,我无需检查新闻/更新,因此使用服务会过度使用并且只使用超出需要的数据。我发现使用Handler是可行的方法。以下是完美运行的实现:
<强>活性起着:强>
public class UpdateServiceActivity extends Activity implements OnClickListener {
private Handler handlerTimer;
private Runnable newsHandler;
@Override
public void onCreate( Bundle savedInstanceState ) {
handlerTimer = new Handler();
newsHandler = new NewsHandler( handlerTimer, this );
handlerTimer.removeCallbacks( newsHandler );
}
@Override
protected void onPause() {
handlerTimer.removeCallbacks( newsHandler );
super.onPause();
}
@Override
protected void onResume() {
handlerTimer.postDelayed( newsHandler, 5000 );
super.onResume();
}
}
<强> NewsHandler 强>
public class NewsHandler implements Runnable {
private static final int THERE_IS_NEWS = 999;
private Handler timerHandler;
private Handler newsEventHandler;
private Context context;
public NewsHandler( Handler timerHandler, Context context ) {
this.timerHandler = timerHandler;
this.newsEventHandler = new NewsEventHandler();
this.context = context;
}
public void run() {
Message msg = new Message();
msg.what = THERE_IS_NEWS;
newsEventHandler.sendMessage( msg );
timerHandler.postDelayed( this, 5000 );
}
private class NewsEventHandler extends Handler {
@Override
public void handleMessage( Message msg ) {
if( msg.what == THERE_IS_NEWS )
Toast.makeText( context, "HandlerMessage recieved! There is news!", Toast.LENGTH_SHORT ).show();
}
};
}