Android 后台任务(六)IntentService
翻译自:http://blog.stylingandroid.com/archives/833
转载请注明:http://blog.csdn.net/liaoqianchuan00/article/details/23949935
IntentService,就像我之前文章中提到的,是个很好的方式去处理一个任务,然后关闭这个服务。在Mannifest中注册一个或者多个启动这个service的Intent Filters,我们也可以在代码中调用startService来启动他。让我们来实现一个IntentService:
public class MyService extends IntentService
{
public static final StringACTION_DO_SOMETHING =
"com.stylingandroid.background.ACTION_DO_SOMETHING";
public static final StringACTION_UPDATE =
"com.stylingandroid.background.ACTION_UPDATE";
public static final StringACTION_PROGRESS =
"com.stylingandroid.background.ACTION_PROGRESS";
public static final StringEXTRA_UPDATE_TEXT = "UPDATE_TEXT";
public static final StringEXTRA_PROGRESS = "PROGRESS";
public static final StringEXTRA_MAX = "MAX";
public MyService()
{
super("MyService" );
}
@Override
protected voidonHandleIntent( Intent intent )
{
if (intent.getAction().equals( ACTION_DO_SOMETHING ) )
{
doSomething();
}
}
private void doSomething()
{
for (int i = 0; i < 5; i++ )
{
try
{
Thread.sleep(2000 );
}
catch( InterruptedException e )
{
}
}
}
}
首先,我们定义了一个service支持的action和Intents中额外值的字段名字。我们必须重写onHandleIntent方法,我们根据intent的action来做出适当的处理。
而doSomething方法就是我们要作的耗时处理,这和之前我们的一系列文章介绍的一样,只是这里我们通过发送broadcasts来发送进度信息和处理结果等。
要注意的是我们这里不需要显示的调用stopSelf, 因为这会在onHandleIntent返回之后自动调用。
还要注意的就是,在IntentService中坐一些长时间的处理的时候,如果设备进入休眠状态,IntentService将可能被停掉。你可以使用WakeLock来解决这个问题,只是要记住在onHandleIntent返回前解除wakeLock。也可以使用Murphy’s的WakefulIntentService。
在我们使用这个IntentService之前,我们需要在Manifest中声明他:
<?xml version="1.0"encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.stylingandroid.background"
android:versionCode="1"
android:versionName="1.0">
<uses-sdkandroid:minSdkVersion="4" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name">
.
.
.
<serviceandroid:name="MyService" >
<intent-filter>
<action
android:name="com.stylingandroid.background.ACTION_DO_SOMETHING"/>
</intent-filter>
</application>
</manifest>
前面文章我们说过,我们认为service是独立于Activityt运行的,但是这并不意味着我们不能在某些时候去更新UI。最简便的方法就是在Activity里面声明和注册一个BroadcastReceiver。让我们在doSomething方法中加入一些broadcasts:
private void doSomething() { for ( int i = 0; i < 5; i++ ) { Intent progressIntent = new Intent( ACTION_PROGRESS ); progressIntent.putExtra( EXTRA_PROGRESS, i ); progressIntent.putExtra( EXTRA_MAX, 4 ); sendBroadcast( progressIntent ); try { Thread.sleep( 2000 ); } catch ( InterruptedException e ) { } } Intent updateIntent = new Intent( ACTION_UPDATE ); updateIntent.putExtra( EXTRA_UPDATE_TEXT, "Finished Service" ); sendBroadcast( updateIntent ); } |
接着我们需要在Activity中声明BroadcastReceiver:
public class MainActivity extends FragmentActivity
{
.
.
.
private classMyServiceReceiver extends BroadcastReceiver
{
@Override
publicvoid onReceive( Context context, Intent intent )
{
if( intent.getAction().equals( MyService.ACTION_PROGRESS ) )
{
intprogress = intent.getIntExtra( MyService.EXTRA_PROGRESS, 0 );
intmax = intent.getIntExtra( MyService.EXTRA_MAX, 0 );
serviceProgress.setMax(max );
serviceProgress.setProgress(progress );
}
if( intent.getAction().equals( MyService.ACTION_UPDATE ) )
{
Stringtext = intent
.getStringExtra(MyService.EXTRA_UPDATE_TEXT );
serviceProgress.setVisibility(View.INVISIBLE );
serviceButton.setVisibility(View.VISIBLE );
Toast.makeText(MainActivity.this, text, Toast.LENGTH_SHORT )
.show();
}
}
}
.
.
.
}
他会处理收到的broadcasts然后更新相关的UI。我们现在需要注册BroadcastReceiver。在这个程序里,我们使用代码来注册这个BroadcastReceiver。当我们注册和取消注册卸载onStart和onStop里面的时候,我们只能在Activity可见的时候才能收到broadcasts。
private MyServiceReceiver receiver = newMyServiceReceiver;
@Override
protected void onStart()
{
super.onStart();
IntentFilter filter = newIntentFilter();
filter.addAction(MyService.ACTION_UPDATE );
filter.addAction(MyService.ACTION_PROGRESS );
registerReceiver( receiver,filter );
}
@Override
protected void onStop()
{
unregisterReceiver( receiver);
super.onStop();
}
最后就是启动service。我们可以直接调用startService:
startService( new Intent(MyService.ACTION_DO_SOMETHING ) );