android开发步步为营之60:IntentService与Service的区别
这个面试的时候,相信是面试官最爱的问题之一。简单的来说,IntentService继承至Service,Service和Acitivity一样是依附于应用主进程的,它本身不是一个进程或者一个线程。一些耗时的操作可能会引起ANR的bug,(本文测试的时候,Service执行20秒没有报ANR),而IntentService,看它的源代码,onCreate()其实是创建了一个新的线程。
/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.app; import android.content.Intent; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; import android.os.Message; public abstract class IntentService extends Service { private volatile Looper mServiceLooper; private volatile ServiceHandler mServiceHandler; private String mName; private boolean mRedelivery; private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { onHandleIntent((Intent)msg.obj); stopSelf(msg.arg1); } } public IntentService(String name) { super(); mName = name; } public void setIntentRedelivery(boolean enabled) { mRedelivery = enabled; } @Override public void onCreate() { super.onCreate(); HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start(); mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); } @Override public void onStart(Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; mServiceHandler.sendMessage(msg); } @Override public int onStartCommand(Intent intent, int flags, int startId) { onStart(intent, startId); return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; } @Override public void onDestroy() { mServiceLooper.quit(); } @Override public IBinder onBind(Intent intent) { return null; } protected abstract void onHandleIntent(Intent intent); }
Looper对象会每次从MessageQueue中获取Intent对象,然后Handler处理消息,调用void onHandleIntent(Intent intent),在这里可以执行一些耗时的比如下载文件等操作。每次调用IntentService都会生成新的HandlerThread,所以不会阻塞UI主线程。如果需要在一个Service里执行耗时操作,那么IntentService是一个很好的选择,不用在Service里面new Thread()或者New AsyncTask()了那么麻烦了。下面再看看我们本实验的demo,对比Service和IntentService对Acitivity的影响。
第一步:创建Service和IntentService
package com.figo.study.service; import android.app.Service; import android.content.Intent; import android.os.IBinder; public class TestService extends Service { @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { try { Thread.sleep(20000); System.out.print("service执行完成"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return super.onStartCommand(intent, flags, startId); } }
/** * */ package com.figo.study.service; import android.app.IntentService; import android.content.Intent; /** * @author Administrator * */ public class TestIntentService extends IntentService { // public TestIntentService(String name) { // // TODO Auto-generated constructor stub // super(name); // } public TestIntentService() { super("TestIntentService"); } /* (non-Javadoc) * @see android.app.IntentService#onHandleIntent(android.content.Intent) */ @Override protected void onHandleIntent(Intent intent) { // TODO Auto-generated method stub try { Thread.sleep(20000); System.out.print("intentService执行完成"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
第二步:AndroidManifest.xml注册Service和Activity
<service android:name="com.figo.study.service.TestService" android:exported="false" > <intent-filter> <action android:name="TestService" /> </intent-filter> </service> <service android:name="com.figo.study.service.TestIntentService" android:exported="false" > <intent-filter> <action android:name="TestIntentService" /> </intent-filter> </service> <activity android:name="com.figo.study.IntentServiceActivity" android:theme="@android:style/Theme.NoTitleBar" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
第三步:创建测试Activity
/** * */ package com.figo.study; import com.figo.study.service.TestIntentService; import com.figo.study.service.TestService; import android.app.Activity; import android.app.IntentService; import android.content.Intent; import android.os.Bundle; /** * @author figo * */ public class IntentServiceActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); try { setContentView(R.layout.activity_intentservice); // 启动一个20秒超时的Service,因为是依附在主线程,可以看到必须等service执行完成之后,页面才会展示出来 // Intent service=new Intent("TestService"); // Intent service = new Intent(IntentServiceActivity.this, // TestService.class); // startService(service); // 启动一个20秒超时的IntentService,因为是新建线程,所以页面立刻就展示出来了 // Intent intentService=new Intent("TestIntentService"); Intent intentService=new Intent(IntentServiceActivity.this,TestIntentService.class); startService(intentService); } catch (Exception e) { e.printStackTrace(); } } }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。