当前位置:K88软件开发文章中心编程语言APP编程Android01 → 文章内容

4.2.2 Service进阶

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-12 6:26:13

本节引言上节我们学习了Service的生命周期,以及两种启动Service的两种方法,本节继续来深入了解Service中的IntentService,Service的使用实例:前台服务与轮询的实现!1.IntentService的使用在上一节后我们已经知道了如何去定义和启动Service,但是如果我们直接把耗时线程放到Service中的onStart()方法中,虽然可以这样做,但是很容易会引起ANR异常(Application Not Responding),而Android的官方在介绍Service有下面这样一段话:直接翻译:1.Service不是一个单独的进程,它和它的应用程序在同一个进程中2.Service不是一个线程,这样就意味着我们应该避免在Service中进行耗时操作于是乎,Android给我们提供了解决上述问题的替代品,就是下面要讲的IntentService;IntentService是继承与Service并处理异步请求的一个类,在IntentService中有一个工作线程来处理耗时操作,请求的Intent记录会加入队列工作流程:客户端通过startService(Intent)来启动IntentService;我们并不需要手动地区控制IntentService,当任务执行完后,IntentService会自动停止;可以启动IntentService多次,每个耗时操作会以工作队列的方式在IntentService的onHandleIntent回调方法中执行,并且每次只会执行一个工作线程,执行完一,再到二这样!再接着是代码演示,网上大部分的代码都是比较Service与IntentService的,定义足够长的休眠时间,演示Service的ANR异常,然后引出IntentService有多好!这里就不演示Service了,网上的都是自定义Service,然后在onStart()方法中Thread.sleep(20000)然后引发ANR异常,有兴趣的可以自己写代码试试,这里的话只演示下IntentService的用法!TestService3.javapublic class TestService3 extends IntentService { private final String TAG = "hehe"; //必须实现父类的构造方法 public TestService3() { super("TestService3"); } //必须重写的核心方法 @Override protected void onHandleIntent(Intent intent) { //Intent是从Activity发过来的,携带识别参数,根据参数不同执行不同的任务 String action = intent.getExtras().getString("param"); if(action.equals("s1"))Log.i(TAG,"启动service1"); else if(action.equals("s2"))Log.i(TAG,"启动service2"); else if(action.equals("s3"))Log.i(TAG,"启动service3"); //让服务休眠2秒 try{ Thread.sleep(2000); }catch(InterruptedException e){e.printStackTrace();} } //重写其他方法,用于查看方法的调用顺序 @Override public IBinder onBind(Intent intent) { Log.i(TAG,"onBind"); return super.onBind(intent); } @Override public void onCreate() { Log.i(TAG,"onCreate"); super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i(TAG,"onStartCommand"); return super.onStartCommand(intent, flags, startId); } @Override public void setIntentRedelivery(boolean enabled) { super.setIntentRedelivery(enabled); Log.i(TAG,"setIntentRedelivery"); } @Override public void onDestroy() { Log.i(TAG,"onDestroy"); super.onDestroy(); } } AndroidManifest.xml注册下Service<service android:name=".TestService3" android:exported="false"> <intent-filter > <action android:name="com.test.intentservice"/> </intent-filter> </service> 在MainActivity启动三次服务:public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent it1 = new Intent("com.test.intentservice"); Bundle b1 = new Bundle(); b1.putString("param", "s1"); it1.putExtras(b1); Intent it2 = new Intent("com.test.intentservice"); Bundle b2 = new Bundle(); b2.putString("param", "s2"); it2.putExtras(b2); Intent it3 = new Intent("com.test.intentservice"); Bundle b3 = new Bundle(); b3.putString("param", "s3"); it3.putExtras(b3); //接着启动多次IntentService,每次启动,都会新建一个工作线程 //但始终只有一个IntentService实例 startService(it1); startService(it2); startService(it3); } } 运行截图:小结:当一个后台的任务,需要分成几个子任务,然后按先后顺序执行,子任务(简单的说就是异步操作),此时如果我们还是定义一个普通Service然后在onStart方法中开辟线程,然后又要去控制线程,这样显得非常的繁琐;此时应该自定义一个IntentService然后再onHandleIntent()方法中完成相关任务!2.Activity与Service通信我们前面的操作都是通过Activity启动和停止Service,假如我们启动的是一个下载的后台Service,而我们想知道Service中下载任务的进度!那么这肯定是需要Service与Activity进行通信的,而他们之间交流的媒介就是Service中的onBind()方法!返回一个我们自定义的Binder对象!基本流程如下:1.自定义Service中,自定义一个Binder类,然后将需要暴露的方法都写到该类中!2.Service类中,实例化这个自定义Binder类,然后重写onBind()方法,将这个Binder对象返回!3.Activity类中实例化一个ServiceConnection对象,重写onServiceConnected()方法,然后获取Binder对象,然后调用相关方法即可!3.一个简单前台服务的实现学到现在,我们都知道Service一般都是运行在后来的,但是Servi

[1] [2]  下一页


4.2.2 Service进阶