码迷,mamicode.com
首页 > 移动开发 > 详细

Android_实用技术(3)—— Service简析(Ⅲ)

时间:2016-04-26 18:54:28      阅读:256      评论:0      收藏:0      [点我收藏+]

标签:

  1、今天我们来分析Service中的一个小技巧:前台服务(Forground Service)

----------------------------------------------------------------------------------------------------------------------------------------

【问题】我们都知道服务是运行在后台的,如果系统出现内存不足的情况,那么此时,系统就可能回收后代的服务,那么我们如何保证服务可以一直运行?

【解决】:在服务中,有一个前台服务的概念,调用startForground()方法。

   我们看看官网对前台服务startForeground()的描述:

  技术分享

    技术分享

  看了官方的解释后,我们再来看看如何使用,上代码:

技术分享
public class MyService extends Service{

  ......

  @Override
  public void onCreate() {
    super.onCreate();
    Intent intent = new Intent(getBaseContext(), MainActivity.class);
    PendingIntent pi = PendingIntent.getActivity(getBaseContext(), 0 , intent, PendingIntent.FLAG_CANCEL_CURRENT);
    Notification no = new Notification.Builder(getBaseContext()) // 启动服务后,在前台添加一个Notification
        .setWhen(System.currentTimeMillis())
        .setSmallIcon(R.mipmap.ic_launcher)
        .setTicker("Create a front desk Service!")
        .setContentTitle("This is a front desk service")
        .setContentText("A service skill!!!")
        .setContentIntent(pi)
        .setAutoCancel(true)
        .setDefaults(Notification.DEFAULT_ALL)
        .build();
    startForeground(1, no);
    Log.d(TAG, "onCreate executed");
  }
}
技术分享

  我们再看一下官方文档:

  技术分享

  以上的代码是在Service的创建中添加了一个Notification,调用startForground()就可以保证:只要服务一直存在,那么在前台就会一直显示这个Notification

  如果我们在onDestroy()中调用stopForground()方法,会销毁这个Notification但是Service还是存活的,此时Service就会面临被System干掉的风险

  如果直接STOP SERVICE,那么Notification和Service都会销毁。 

----------------------------------------------------------------------------------------------------------------------------------------

  2、接下来,我们再来看一个Service的另外一个小技巧:IntentService

【问题】我们知道服务的代码逻辑是在主线程中执行的,如果我们在主线程中需要执行一些耗时的操作,那么很有可能出现ANR(程序暂无响应)的状况。

  这个时候,我们可以采用Android的多线程编程(小编在之前的 AsyncTask 贴中讲解过多线程,可以回顾)的方式,我们来看一段代码:

public class MyService extends Service{
  @Nullable
  @Override
  public IBinder onBind(Intent intent) {
    return null;
  }
  @Override
  public 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{
  @Nullable
  @Override
  public IBinder onBind(Intent intent) {
    return null;
  }
  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
    new Thread(new Runnable() {
      @Override
      public void run() {
        // 处理具体的逻辑                     // 开启一个线程处理耗时操作
        stopSelf(); // 让服务执行完逻辑后自行停止       }     }).start();     return super.onStartCommand(intent, flags, startId);   } }

  上面的代码就是一个标准的Service的书写形式,主要包含两个知识点:Thread子线程的创建stopSelf()方法的调用

  其实,在一般的使用过程中,一部分程序员很容易忘记以上两个要点,存在遗忘,那么有没有更好的办法能够实现上面两个需求呢?

【解决】在Android中,专门提供了一个IntentService类(android.app.IntentService),这个类就能很好的满足我们的需求!我们直接通过代码来看:

  (1)新建一个MyIntentService类继承自IntentService,代码:

public class MyIntentService extends IntentService{

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

  @Override
  protected void onHandleIntent(Intent intent) {
    Log.d("MyIntentService", "MyIntentServiceThread id is " + Thread.currentThread().getId());
  }

  @Override
  public void onDestroy() {
    super.onDestroy();
    Log.d("MyIntentService", "onDestroy executed");
  }
}

  以上代码做了几件事:

  1、提供了一个无参的构造方法,并且调用了父类的有参构造函数(这个就不需要我说为什么了吧);

  2、子类实现父类的onHandleIntent()抽象方法,这个方法好就好在,它是一个已经运行在子线程中的方法。也就是说,服务调用了它,那么执行的逻辑就如同Thread子线程。

        onHandleIntent = Thread().start() + stopSelf()

  3、onHandleIntent()执行完后会销毁服务?会selfStop()?接着往下看代码。

----------------------------------------------------------------------------------------------------------------------------------------

  (2)在xml文件中,创建一个MyIntentService服务按钮:

<Button
  android:id="@+id/start_intent_service"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:text="@string/intent_service"/>

  (3)接下来,修改MainActivity中的代码:

public class MainActivity extends Activity {
  @Override   
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);     setContentView(R.layout.activity_main);     Button startIntentService
= (Button) super.findViewById(R.id.start_intent_service);     startIntentService.setOnClickListener(new View.OnClickListener() {
      @Override       
public void onClick(View v) {         Log.d("MyIntentService", "MainActivity Thread id is " + Thread.currentThread().getId()); // 查看主线程的id         Intent intentService = new Intent(getBaseContext(), MyIntentService.class);         startService(intentService);       }     });   } }

  (4)最后,在AndroidMainfest中注册服务:

<service android:name=".MyIntentService" />

【结果】:直接看一下代码执行的效果。

技术分享

  从打出的LOG可以看出:

  (1)MyIntentService和MainActivity所在进程的id不一样的;

  (2)onHandleIntent()方法在执行完逻辑后确实销毁了服务,效果等同于stopSelf()。

  从上面的分析可以看出onHandleIntent()方法确实相当的好用!

Android_实用技术(3)—— Service简析(Ⅲ)

标签:

原文地址:http://www.cnblogs.com/pepsimaxin/p/5435958.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!