Android面试系列文章2018之Android部分IntentService机制篇

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ClAndEllen/article/details/79346624

Android面试系列文章2018之Android部分IntentService机制篇

IntentService知识体系图

1.IntentService是什么?

  它的优先级高于Service。
  IntentService是继承处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentServiced的方式和启动传统的Service一样,同时,当任务执行完成后,IntentService会自动停止,而不需要我们手动去控制或stopSelf()。另外,可以启动IntentService多次,而每一个耗时操作会以工作队列的方式在IntentService的onHandlerIntent回调方法中执行,并且,每次只执行一个工作线程,执行完第一个在执行第二个。

  a.它本质是一种特殊的Service,继承自Service并且本身就是一个抽象类。

  b.它内部是由HandlerThread和Handler实现异步操作。

2.IntentService的使用方法

  创建IntentService时,只需要实现onHandlerIntent和构造方法,onHandlerIntent为异步方法,可以执行耗时操作。我们接下来来一个例子熟悉熟悉用法:

MyIntentService代码:

public class MyIntentService extends IntentService {
    public static final String DOWNLOAD_URL="download_url";
    public static final String INDEX_FLAG="index_flag";
    public static UpdateUI updateUI;


    public static void setUpdateUI(UpdateUI updateUIInterface){
        updateUI=updateUIInterface;
    }

    public MyIntentService(){
        super("MyIntentService");
    }

    /**
     * 实现异步任务的方法
     * @param intent Activity传递过来的Intent,数据封装在intent中
     */
    @Override
    protected void onHandleIntent(Intent intent) {

        //在子线程中进行网络请求
        Bitmap bitmap=downloadUrlBitmap(intent.getStringExtra(DOWNLOAD_URL));
        Message msg1 = new Message();
        msg1.what = intent.getIntExtra(INDEX_FLAG,0);
        msg1.obj =bitmap;
        //通知主线程去更新UI
        if(updateUI!=null){
            updateUI.updateUI(msg1);//这里其实是通过Handler将msg1发送到主线程更新UI,逻辑代码在Activity中
        }
    }

    @Override
    public IBinder onBind(Intent intent) {

        return super.onBind(intent);
    }


    public interface UpdateUI{
        void updateUI(Message message);
    }


    private Bitmap downloadUrlBitmap(String urlString) {
        HttpURLConnection urlConnection = null;
        BufferedInputStream in = null;
        Bitmap bitmap=null;
        try {
            final URL url = new URL(urlString);
            urlConnection = (HttpURLConnection) url.openConnection();
            in = new BufferedInputStream(urlConnection.getInputStream(), 8 * 1024);
            bitmap= BitmapFactory.decodeStream(in);
        } catch (final IOException e) {
            e.printStackTrace();
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
            try {
                if (in != null) {
                    in.close();
                }
            } catch (final IOException e) {
                e.printStackTrace();
            }
        }
        return bitmap;
    }

}

IntentServiceActivity代码:

public class IntentServiceActivity extends Activity implements MyIntentService.UpdateUI{
    /**
     * 图片地址集合
     */
    private String url[] = {
        "图片地址1",
        "图片地址2",
        "图片地址3",
        "图片地址4",
        "图片地址5",
        "图片地址6",
        "图片地址7"
    };

    private static ImageView imageView;
    private static final Handler mUIHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            imageView.setImageBitmap((Bitmap) msg.obj);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_intent_service);
        imageView = (ImageView) findViewById(R.id.image);

        Intent intent = new Intent(this,MyIntentService.class);
        for (int i=0;i<7;i++) {//循环启动任务
            intent.putExtra(MyIntentService.DOWNLOAD_URL,url[i]);
            intent.putExtra(MyIntentService.INDEX_FLAG,i);
            startService(intent);
        }
        MyIntentService.setUpdateUI(this);
    }

    //必须通过Handler去更新,该方法为异步方法,不可更新UI
    @Override
    public void updateUI(Message message) {
        mUIHandler.sendMessageDelayed(message,message.what * 1000);
    }
}

  代码比较简单,通过for循环多次去启动IntentService,然后去下载图片,注意即使我们多次启动IntentService,但IntentService的实例只有一个,这跟传统的Service是一样的,最终IntentService会去调用onHandleIntent执行异步任务。这里可能我们还会担心for循环去启动任务,而实例又只有一个,那么任务会不会被覆盖掉呢?其实是不会的,因为IntentService真正执行异步任务的是HandlerThread+Handler,每次启动都会把下载图片的任务添加到依附的消息队列中,最后由HandlerThread+Handler去执行。

3.IntentService的原理机制

https://www.cnblogs.com/feidu/p/8074268.html

4.IntentService和Service的区别

第一:简单描述一下Service

Service是用于后台服务的,当应用程序被挂到后台的时候,为了保证应用某些组件仍然可以工作而引入了Service这个概念。

那么这里面要强调的是Service不是独立的进程,也不是独立的线程,它是依赖于应用程序的主线程的,也就是说,在更多时候不建议在Service中编写耗时的逻辑和操作,否则会引起ANR,为了解决这样的问题,引入了IntentService

第二:简单描述一下IntentService

IntentService是继承Service的,那么它包含了Service的全部特性,当然也包含service的生命周期。

那么与service不同的是,IntentService在执行onCreate操作的时候,内部开了一个线程,去执行耗时操作

IntentService:异步处理服务,新开一个线程:handlerThread在线程中发消息,然后接受处理完成后,会清理线程,并且关掉服务。

IntentService有以下特点:

  • (1) 它创建了一个独立的工作线程来处理所有的通过onStartCommand()传递给服务的intents。
  • (2) 创建了一个工作队列,来逐个发送intent给onHandleIntent()。
  • (3) 不需要主动调用stopSelft()来结束服务。因为,在所有的intent被处理完后,系统会自动关闭服务。
  • (4) 默认实现的onBind()返回null
  • (5) 默认实现的onStartCommand()的目的是将intent插入到工作队列中

没有更多推荐了,返回首页