Android面试系列文章2018之Android部分IntentService机制篇
Android面试系列文章2018之Android部分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插入到工作队列中
更多相关文章
- Android中SyncTask的使用
- android主线程报ANR的问题!
- android 预装第三方apk的方法
- Android的线程使用来更新UI----Thread、Handler、Looper、TimerT
- Android的线程使用来更新UI----Thread、Handler、Looper、TimerT
- Android消息机制的Handler
- E/错误(3907): android.view.ViewRootImpl$CalledFromWrongThrea
- android的Handler
- Android的Message机制(简单小结)