Android Service & IntentService学习总结

目录

1. Service介绍

1.1 Service是什么,有什么作用

2. Service生命周期

3. 自定义Service例子

3.1 观察Service生命周期

3.2 绑定Service例子

4. IntentService

4.1 IntentService是什么

4.2 IntentService与Service的区别

4.3 IntentService例子Demo


 

1. Service介绍

Android 四大组件之Service(中译:服务)学习。

1.1 Service是什么,有什么作用

Service(中译:服务)是一个组件,用于在后台执行长时间运行的操作,如播放音乐、处理网络事务、交互内容提供者等。Service没有任何UI界面,所以不需要与用户交互,而且即使应用程序被破坏,它也能正常工作。

2. Service生命周期

Service有两种形式,分别是Start(启动)和Bound(绑定):

Android Service & IntentService学习总结_第1张图片 左边是Start Service;右边为Bound Service

Start(启动):当app组件(如Activity)通过调用startService()来启动服务,服务一旦启动,就可以在后台无限期运行,即使启动它的组件(如Activity)被销毁。可以通过调用stopService()方法来停止服务,而且服务本身可以通过调用stopSelf()方法来自行停止。

Bounded(绑定):当app组件通过调用bindService()方法绑定到服务时,服务将被绑定。绑定服务提供了一个client-server interface(客户机-服务器接口),该接口允许组件与服务交互、发送请求、获取结果。在所有客户端解除服务绑定之前,无法停止服务。

public class ExampleService extends Service {
    int startMode;       //指示在服务被终止时如何行为
    IBinder binder;      //用于绑定客户的接口
    boolean allowRebind; //指示是否应该使用onRebind()
 
    /**
     * 在最初创建服务时(在调用onStartCommand()或onBind()之前),系统将调用此方法以执行一次性设置过程。
     * 如果服务已经在运行,则不会调用此方法。
     */
    @Override
    public void onCreate() {
        //正在创建服务
    }

    /**
     * 当另一个组件(例如活动)请求启动服务时,系统通过调用startService()来调用此方法。
     * 执行此方法时,服务将启动并可以无限期在后台运行。
     * 如果执行此操作,则 必须 通过调用stopSelf()或stopService()在服务完成后停止该服务。如果只想提供绑定,则不需要实现此方法。
     * @param intent
     * @param flags
     * @param startId
     * @return
     */
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //调用startService(),服务正在启动 
        return mStartMode;
    }

    /**
     * 在call bindService()方法时调用。在此方法的实现中,必须提供一个接口,客户端可以通过返回IBinder使用该接口与服务进行通信。
     * 当你实现绑定时,必须始终实现此方法。但是,如果不允许绑定,则应返回null。
     * @param intent
     * @return
     */
    @Override
    public IBinder onBind(Intent intent) {
        //客户端使用bindService()来绑定到服务
        return mBinder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        //所有客户端都使用unbindService()来解除绑定
        return mAllowRebind;
    }
    @Override
    public void onRebind(Intent intent) {
        //重新绑定,指调用onUnbind()之后,客户端使用bindService()重新绑定到服务
    }

    /**
     * 当服务不再使用并被销毁时,系统将调用此方法,所以这是服务收到的最后一个呼叫。
     * 您的服务应实现此目的,以清理所有资源,例如线程,注册的侦听器或接收器。
     */
    @Override
    public void onDestroy() {
        //服务不再使用,正在被销毁
    }
}

3. 自定义Service例子

3.1 观察Service生命周期

简单的创建一个Service,然后启动它-然后销毁它,利用Toast显示状态,效果如下所示:

start创建服务,stop停止服务

1. 创建MyService服务,添加Toast用于显示Service状态

public class MyService extends Service {
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Toast.makeText(this, "Service onCreate", Toast.LENGTH_SHORT).show();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Toast.makeText(this, "onStartCommand", Toast.LENGTH_SHORT).show();
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Toast.makeText(this, "Service onDestroy", Toast.LENGTH_SHORT).show();
    }

}

2. 在AndroidManifest签单文件中定义声明我们刚刚创建的MyService。(当然这一步可以让Android Studio来帮我们完成)




    
        //声明我们的服务
        
        

        
            
                

                
            
        
    

3. 在我们的app组件-MainActivity.java文件中进行Service的操作,(启动服务,停止服务)

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button startBtn = findViewById(R.id.start_service_btn);
        startBtn.setOnClickListener(this);
        Button stopBtn = findViewById(R.id.stop_service_btn);
        stopBtn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.start_service_btn:
                //启动服务
                Intent intent = new Intent(this, MyService.class);
                startService(intent);
                break;
            case R.id.stop_service_btn:
                //停止服务
                Intent stopIntent = new Intent(this, MyService.class);
                stopService(stopIntent);
                break;
            default:
                break;
        }
    }
}

3.2 绑定Service例子

相对比与Start Service,bound service会相对复杂些,见下例所示:

具体代码如下:

public class MyBoundService extends Service {
    private final IBinder mBinder = new MyBinder();
    private final Random mGenerator = new Random();

    public MyBoundService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    class MyBinder extends Binder {
        MyBoundService getService() {
            //返回MyBoundService的实例
            return MyBoundService.this;
        }
    }

    public int getRandomNumber() {
        return mGenerator.nextInt(100);
    }
}
public class BoundServiceTestActivity extends AppCompatActivity {
    private MyBoundService boundService;
    private boolean isBoundService = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bound_service_test);

        Button getRandomBtn = findViewById(R.id.get_number_btn);
        getRandomBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isBoundService) {
                    Toast.makeText(BoundServiceTestActivity.this,
                            "random Number is: " + boundService.getRandomNumber(),
                            Toast.LENGTH_SHORT)
                            .show();
                }
            }
        });

    }

    @Override
    protected void onStart() {
        super.onStart();
        Intent intent = new Intent(this, MyBoundService.class);
        bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (isBoundService) {
            unbindService(serviceConnection);
            isBoundService = false;
        }

    }

    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            MyBoundService.MyBinder binder = (MyBoundService.MyBinder) service;
            boundService = binder.getService();
            isBoundService = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            isBoundService = false;
        }
    };
}

 

4. IntentService

4.1 IntentService是什么

IntentService是Service的子类,继承于Service类,用于处理需要异步请求的任务。用户通过调用Context.StartService(Intent)发送请求,服务根据需要启动,使用工作线程依次处理每个Intent,并在处理完所有工作后自身停止服务。

使用时,扩展IntentService并实现onHandleIntent(android.content.Intent)。IntentService接收Intent,启动工作线程,并在适当时机停止服务。

所有的请求都在同一个工作线程上处理,一次处理一个请求,所以处理完所以的请求可能会花费很长的时间,但由于IntentService是另外创建的线程来工作,所以保证不会阻止App的主线程。

4.2 IntentService与Service的区别

从何时使用,触发方法,运行环境,何时停止四个方面分析。

1、何时使用:

Service用于没有UI工作的任务,但不能执行长任务(长时间的任务),如果需要Service来执行长时间的任务,则必须手动开启一个线程来执行该Service。

IntentService可用于执行不与主线程沟通的长任务。

2、触发方法:

Service通过调用 startService() 方法来触发。

而IntentService通过Intent来触发,开启一个新的工作线程,并在线程上调用 onHandleIntent() 方法。

3、运行环境:

Service 在App主线程上运行,没有与用户交互,即在后台运行,如果执行长时间的请求任务会阻止主线程工作。

IntentService在自己单独开启的工作线程上运行,即使执行长时间的请求任务也不会阻止主线程工作。

4、何时停止

如果执行了Service,我们是有责任在其请求任务完成后关闭服务,通过调用 stopSelf() 或 stopService()来结束服务。

IntentService会在执行完所有的请求任务后自行关闭服务,所以我们不必额外调用 stopSelf() 去关闭它。

4.3 IntentService例子Demo

Android Service & IntentService学习总结_第2张图片

通过Android Studio来创建我们的MyIntentService。

public class MyIntentService extends IntentService {

    private static final String TAG = "MyIntentService";
    public static final String DOWNLOAD_ACTION = "DOWNLOAD_ACTION";
    public static final String READ_ACTION = "READ_ACTION";
    public static final String TEST_AUTHOR = "TEST_AUTHOR";

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

    /**
     * 进行一些耗时操作
     * @param intent 通过startService(Intent intent)方法传入
     */
    @Override
    protected void onHandleIntent(Intent intent) {
        if (intent != null) {
            final String action = intent.getAction();
            String author = intent.getExtras().getString(TEST_AUTHOR);
            //模拟下载动作
            if (DOWNLOAD_ACTION.equals(action)) {
                for (int i = 0; i < 10; i++) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Log.d(TAG, author + " " + action + " " + i);
                }
            }
            //模拟读操作
            if (READ_ACTION.equals(action)) {
                for (int i = 0; i < 10; i++) {
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Log.d(TAG, author + " " + action + " " + i);
                }
            }
        }

    }
}

如果你是手动创建IntentService的,得在AndroidManifest.xml文件中注册该IntentService,如果通过Android Studio创建则免去这一步了。


在主线程中开启服务。

public class IntentServiceActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_intent_service);

        //模拟 Jere 做下载动作
        Intent intent = new Intent(this, MyIntentService.class);
        intent.setAction(MyIntentService.DOWNLOAD_ACTION);
        intent.putExtra(MyIntentService.TEST_AUTHOR, "Jere");
        startService(intent);

        //模拟 James 做读取动作
        Intent jamesIntent = new Intent(this, MyIntentService.class);
        jamesIntent.setAction(MyIntentService.READ_ACTION);
        jamesIntent.putExtra(MyIntentService.TEST_AUTHOR, "James");
        startService(jamesIntent);
    }
}

效果如下:

Android Service & IntentService学习总结_第3张图片

 

END~

 

你可能感兴趣的:(Android)