Android Service总结05 之IntentService

版本

版本说明

发布时间

发布人

V1.0

添加了IntentService的介绍和示例

2013-03-17

Skywang

   


1 IntentService介绍

IntentService继承与Service,它最大的特点是对服务请求逐个进行处理。当我们要提供的服务不需要同时处理多个请求的时候,可以选择继承IntentService。

IntentService有以下特点:

(1) 它创建了一个独立的工作线程来处理所有的通过onStartCommand()传递给服务的intents。

(2) 创建了一个工作队列,来逐个发送intent给onHandleIntent()。

(3) 不需要主动调用stopSelft()来结束服务。因为,在所有的intent被处理完后,系统会自动关闭服务。

(4) 默认实现的onBind()返回null

(5) 默认实现的onStartCommand()的目的是将intent插入到工作队列中。

继承IntentService的类至少要实现两个函数:构造函数和onHandleIntent()函数。要覆盖IntentService的其它函数时,注意要通过super调用父类的对应的函数。


2 IntentService示例

示例说明:编写一个activity,包含2个按钮和1个进度条,2个按钮分别是开始按钮、结束按钮。点击“开始”按钮:进度条开始加载;“开始”变成“重启”按钮;显示“结束”按钮(默认情况,“结束”按钮是隐藏状态)。

IntentService的示例包括2个类:

IntentServiceSub.java —— 继承IntentService,并新建一个线程,用于每隔200ms将一个数字+2,并通过广播发送出去

IntentServiceTest.java —— 启动IntentServiceSub服务,接收它发送的广播,并根据广播中的数字值来更新进度条

IntentServiceSub.java的内容如下:

package com.test;import android.app.IntentService;import android.content.Intent;import android.util.Log;import java.lang.Thread;/** * @desc IntentService的实现类:每隔200ms将一个数字+2并通过广播发送出去 * @author skywang * */public class IntentServiceSub extends IntentService {    private static final String TAG = "skywang-->IntentServiceTest";        // 发送的广播对应的action    private static final String COUNT_ACTION = "com.test.COUNT_ACTION";        // 线程:用来实现每隔200ms发送广播    private static CountThread mCountThread = null;    // 数字的索引    private static int index = 0;        public IntentServiceSub() {        super("IntentServiceSub");        Log.d(TAG, "create IntentServiceSub");    }    @Override    public void onCreate() {        Log.d(TAG, "onCreate");        super.onCreate();    }        @Override    public void onDestroy() {        Log.d(TAG, "onDestroy");                super.onDestroy();    }        @Override    protected void onHandleIntent(Intent intent) {        Log.d(TAG, "onHandleIntent");        // 非首次运行IntentServiceSub服务时,执行下面操作        // 目的是将index设为0        if ( mCountThread != null) {            index = 0;            return;        }                // 首次运行IntentServiceSub时,创建并启动线程        mCountThread = new CountThread();        mCountThread.start();    }        private class CountThread extends Thread {        @Override         public void run() {            index = 0;            try {                while (true) {                    // 将数字+2,                    index += 2;                                                            // 将index通过广播发送出去                    Intent intent = new Intent(COUNT_ACTION);                    intent.putExtra("count", index);                    sendBroadcast(intent);//                    Log.d(TAG, "CountThread index:"+index);                                        // 若数字>=100 则退出                    if (index >= 100) {                        if ( mCountThread != null)                            mCountThread = null;                                                return ;                    }                                        // 200ms                    this.sleep(200);                }            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}

IntentServiceTest.java的内容如下:

package com.test;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ProgressBar;import android.content.Intent;import android.content.IntentFilter;import android.content.Context;import android.content.BroadcastReceiver;import android.util.Log;/** * @desc 创建一个activity,包含2个按钮(开始/结束)和1个ProgressBar *        点击“开始”按钮,显示“结束”按钮,并启动ProgressBar。 *        点击“结束”按钮,结束ProgressBar的进度更新 * @author skywang * */public class IntentServiceTest extends Activity {    /** Called when the activity is first created. */    private static final String TAG = "skywang-->IntentServiceTest";    private static final String COUNT_ACTION = "com.test.COUNT_ACTION";    private CurrentReceiver mReceiver;    private Button mStart = null;    private Button mStop = null;    private Intent mIntent = null;    private Intent mServiceIntent = new Intent("com.test.subService");     private ProgressBar mProgressBar = null;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.intent_service_test);                mStart = (Button) findViewById(R.id.start);        mStart.setOnClickListener(new View.OnClickListener() {                        @Override            public void onClick(View arg0) {                Log.d(TAG, "click start button");                // 显示“结束”按钮                mStop.setVisibility(View.VISIBLE);                // 将“开始”按钮更名为“重启”按钮                mStart.setText(R.string.text_restart);                // 启动服务,用来更新进度                if (mServiceIntent == null)                     mServiceIntent = new Intent("com.test.subService");                startService(mServiceIntent);            }        });                mStop = (Button) findViewById(R.id.stop);        mStop.setOnClickListener(new View.OnClickListener() {                        @Override            public void onClick(View arg0) {                Log.d(TAG, "click stop button");                if (mServiceIntent != null) {                    // 结束服务。                    // 注意:实际上这里并没有起效果。因为IntentService的特性所致。                    // IntentService的声明周期特别段,在startService()启动后,立即结束;所以,                    // 再调用stopService()实际上并没有起作用,因为服务已经结束!                    stopService(mServiceIntent);                    mServiceIntent = null;                }            }        });        mStop.setVisibility(View.INVISIBLE);                mProgressBar = (ProgressBar) findViewById(R.id.pbar_def);        // 隐藏进度条        mProgressBar.setVisibility(View.INVISIBLE);                // 动态注册监听COUNT_ACTION广播        mReceiver = new CurrentReceiver();        IntentFilter filter = new IntentFilter();        filter.addAction(COUNT_ACTION);        this.registerReceiver(mReceiver, filter);    }        @Override      public void onDestroy(){          super.onDestroy();            if(mIntent != null)            stopService(mIntent);                if(mReceiver != null)            this.unregisterReceiver(mReceiver);    }        /**     * @desc 更新进度条     * @param index     */    private void updateProgressBar(int index) {        int max = mProgressBar.getMax();        if (index < max) {            // 显示进度条            mProgressBar.setVisibility(View.VISIBLE);            mProgressBar.setProgress(index);        } else {            // 隐藏进度条            mProgressBar.setVisibility(View.INVISIBLE);            // 隐藏“结束”按钮            mStop.setVisibility(View.INVISIBLE);            // 将“重启”按钮更名为“开始”按钮            mStart.setText(R.string.text_start);        }//        Log.d(TAG, "progress : "+mProgressBar.getProgress()+" , max : "+max);    }        /**     * @desc 广播:监听COUNT_ACTION,获取索引值,并根据索引值来更新进度条     * @author skywang     *     */    private class CurrentReceiver extends BroadcastReceiver {        @Override        public void onReceive(Context context, Intent intent) {            String action  = intent.getAction();            if (COUNT_ACTION.equals(action)) {                int index = intent.getIntExtra("count", 0);                updateProgressBar(index);            }        }    }}

layout文件intent_service_test.xml的内容如下:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="match_parent"    android:layout_height="match_parent"    >        <LinearLayout        android:orientation="horizontal"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        >        <Button            android:id="@+id/start"              android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:text="@string/text_start"            />        <Button            android:id="@+id/stop"              android:layout_width="wrap_content"             android:layout_height="wrap_content"            android:text="@string/text_stop"            />            </LinearLayout>    <ProgressBar        android:id="@+id/pbar_def"        android:layout_width="match_parent"        android:layout_height="wrap_content"        style="@android:style/Widget.ProgressBar.Horizontal"        android:max="100"        android:progress="0"        /></LinearLayout>

manifest代码如下:

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"      package="com.test"      android:versionCode="1"      android:versionName="1.0">    <uses-sdk android:minSdkVersion="8" />    <application android:icon="@drawable/icon" android:label="@string/app_name">        <activity             android:name=".IntentServiceTest"            android:screenOrientation="portrait"            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=".IntentServiceSub">            <intent-filter>                <action android:name="com.test.subService" />            </intent-filter>        </service>            </application></manifest>

点击下载:示例源代码

程序截图如下:



更多service内容:

1Android Service总结01 目录

2Android Service总结02 service介绍

3Android Service总结03 之被启动的服务 -- Started Service

4Android Service总结04 之被绑定的服务 -- Bound Service

5Android Service总结05 之IntentService

6Android Service总结06 之AIDL


参考文献

1,Android API文档: http://developer.android.com/guide/components/services.html

更多相关文章

  1. android sdk manager upgrade
  2. android 之 service
  3. Android(安卓)Activity栈管理 制定关闭某一个Activity,关闭所有A
  4. android 如何通过包名杀死指定的进程
  5. 三十、Google Map导航应用
  6. Android动态布局
  7. Android里面从Dialog中获取返回值并写入指定TextView组件
  8. android 触摸事件和点击事件执行顺序
  9. Android(安卓)APP--编写简单的答题器

随机推荐

  1. android开发笔记之LayoutInflater的理解
  2. android图片压缩工具类分享
  3. Android(安卓)Camera预览左右上下镜像
  4. Android设置全屏两种方式
  5. 下拉列表
  6. Handle Android Out of memory exception
  7. 每天学习一个Android中的常用框架——0.
  8. Android ContextThemeWrapper cannot be
  9. Android 的ANR 问题解决
  10. Android之RxPermissions用kotlin写没反应