zoukankan      html  css  js  c++  java
  • android: 使用 IntentService

    9.5.2 使用 IntentService

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

    public class MyService extends Service {


    @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 {


    @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);
    }

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

    public class MyIntentService extends IntentService {


    public MyIntentService() {
    super("MyIntentService"); // 调用父类的有参构造函数
    }


    @Override
    protected void onHandleIntent(Intent intent) {
    // 打印当前线程的id
    Log.d("MyIntentService", "Thread id is " + Thread.currentThread(). getId());
    }


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

    }


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

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"
    android:orientation="vertical" >
    ……
    <Button android:id="@+id/start_intent_service" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Start IntentService" />
    </LinearLayout>
    然后修改 MainActivity 中的代码,如下所示:

    public class MainActivity extends Activity implements OnClickListener {
    ……
    private Button startIntentService;


    @Override
    protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
    ……
    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;
    }
    }
    }
    可以看到,我们在 Start IntentService 按钮的点击事件里面去启动 MyIntentService 这个服 务,并在这里打印了一下主线程的 id,稍后用于和 IntentService 进行比对。你会发现,其实 IntentService 的用法和普通的服务没什么两样。
    最后仍然不要忘记,服务都是需要在 AndroidManifest.xml 里注册的,如下所示:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.servicetest"
    android:versionCode="1"
    android:versionName="1.0" >
    ……
    <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" >
    ……
    <service android:name=".MyIntentService"></service>
    </application>
    </manifest>
    现在重新运行一下程序,界面如图 9.13 所示。

    图 9.13

    点击 Start IntentService 按钮后,观察 LogCat 中的打印日志,如图 9.14 所示。

     

    图 9.14

    可以看到,不仅 MyIntentService 和 MainActivity 所在的线程 id 不一样,而且 onDestroy() 方法也得到了执行,说明 MyIntentService 在运行完毕后确实自动停止了。集开启线程和自动 停止于一身,IntentService 还是博得了不少程序员的喜爱。

  • 相关阅读:
    android中textview字数过长解决方法
    Android的EditText无法自动弹出输入法问题 .
    android中dip、dp、px、sp和屏幕密度
    android横竖屏切换 判断activity 是横屏还是竖屏
    设置ListView中图片的大小大方法 Android
    TextView属性详细分析
    ArcGIS API For Silverlight 实例分析
    Visual Studio 2008 里修改数据库表结构报错 解决办法
    未能加载文件或程序集“xxx”或它的某一个依赖项。生成此程序集的运行时比当前加载的运行时新,无法加载此程序集
    SuperMap iClient 6R for Silverlight 产品简介及Beta测试软件下载地址
  • 原文地址:https://www.cnblogs.com/zgqys1980/p/5478668.html
Copyright © 2011-2022 走看看