全面升级Android面试之IntentService面试题集

来源:互联网 发布:iphone移轴摄影知乎 编辑:程序博客网 时间:2024/06/18 05:33

(一)什么是IntentService?为什么要使用IntentService?

众所周知,服务都是默认运行在主线程中i的,如果直接在服务里去处理一些耗时的逻辑,就很容易出现ANR(Application Not Responding)的情况。
所以这个时候就需要用到Android多线程编程的技术了,我们应该在服务的每一个具体的方法里开启一个子线程,然后在这里去处理那些耗时的逻辑。因此一个比较标准的服务就可以写成如下形式:

public class MyService extends Service{...@Overridepublic int onStartCommand(Intent intent,int flags,int startId){     new Thread(new Runnable() {     @Override     public void run(){     //处理逻辑     }     });.start;     return super.onStartCommand(intent,flags,startId);     }    }

但是这种服务一旦启动之后,就会一直处于运行状态,必须调用stopService()或者stopSelf()方法才能让服务停止下来。所以,如果想要实现让一个服务在执行完毕后停止的功能,就可以这样写:

public class MyService extends Service{...@Overridepublic int onStartCommand(Intent intwent,int flags,int startId){new Thread(new Runnable(){@Override//处理逻辑stopSelf();}}).start();return super.onStartCommand(intent,flags,startId);}}

虽然这种写法并不复杂,但是总会有一些程序员忘记开启线程,或者忘记调用stopself()方法。为了可以简单地创建一个异步的,自动停止的服务,Android专门提供了一个IntentService类,这个类很好的解决了前面提到的两种尴尬,下面我们来看一下它的用法。

(二) IntentService的用法

首先新建一个MyIntentService类继承自IntentService,代码如下所示:

public class MyIntentService extends IntentService{   public MyIntentService(){      super("MyIntentService"); //调用父类的有参构造函数@Override   protected void onHandlerIntent(Intent intent){       //打印当前线程的id       Log.d("MyIntentService","Thread id is"+       Thread.currentThread().getId());       }       @Override       public void onDestroy() {          super.onDestroy();          Log.d("MyIntentService","onDestroy executed");   }        }  

这里首先要提供一个无参的构造函数,并且必须在其内部调用父类的有参构造函数。然后要在其子类中去实现onHandlerIntent()这个抽象方法,在这个方法中可以去处理一些具体的逻辑,而且不用担心ANR的问题,因为这个方法已经在子线程中运行的了。这里为了证实一下,我们在onHandlerIntent()方法中打印了当前线程的id。另外根据IntentService的特性,这个服务在运行结束后应该是会自动停止的,我们又重写了onDestroy()方法,在这里也打印了一行日志,以证实服务是不是停止掉了。

接下来修改主活动activity_main.xml中的代码,加入一个用于启动MyIntentService这个服务的按钮,如下所示:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/androidandroid:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent">...<Buttonandroid:id="@+id/start_intent_service"android:layout_width="match_parent"android:layout_height="wrap_content"androiid:text="Start IntentService"/></LinearLayout>

然后修改MainActivity中的代码,如下所示:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{@Overrideprotected void onCreate(Bundle savedInstanceState){    super.onCreate(savedInstanceState);    setContentView(R.id.activity_main);    Button startIntentService=(Button)findViewById(R.id.start_intent_service); startIntentService.setOnClickListener(this); } @Override public void onClick(View v){    switch(v.getId()) {    ...    case R.id.start_intent_service:    //打印主线程的id    Log.d("MainActivity","Thread id        is"+Thread.currentThread().getId());Intent intentService=new Intent(this,MyIntentService.class);startService(intentService);      break;  default:   break;}}}    

可以看到,我们在StartIntentService按钮的点击事件里其去启动MyIntentService这个服务,并在这里打印一下主线程的id,稍后用于和IntentService进行比对。你会发现,其实IntentService的用法和普通的服务没什么两样。

最后不要忘记,服务都是需要在AndroidManifest里注册的。如下所示:

<manifest xmlns:android="................."package="com.example.servicetest"><application.........................<service android:name=".MyIntentService" /></application></manifest>

总结 :
IntentService与service的区别

ntentService是继承并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentService的方式和启动传统的Service一样,同时,当任务执行完后,IntentService会自动停止,而不需要我们手动去控制或stopSelf()。另外,可以启动IntentService多次,而每一个耗时操作会以工作队列的方式在IntentService的onHandleIntent回调方法中执行,并且,每次只会执行一个工作线程,执行完第一个再执行第二个,以此类推。它本质上就是一个封装了HandlerThread和Handler的异步框架
原创粉丝点击