版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
/** * Android四大组件之一,Service 是长期运行在后台的应用程序组件。 * Service 不是进程,也不是线程,它和应用程序在同一个进程中 * Service中不能做耗时操作,运行在主线程中。 */
Service应用场景
后台播放音乐,定位服务,每隔一定时间和服务器进行交互。等。
service两种启动方式,和生命周期
/** * > startService: * Service在系统中被启动多次,onCreate只会执行一次,onStartCommand方法调用次数和启动次数一致 * * > stopService * 调用stopService后,内部会执行onDestroy方法,如果一个Service被绑定了,在没有解绑的前提下,调用stopService是无效的 * * > bindService * 绑定Service内部会调用onCreate,onBind * * > unBindService * 解绑Service,内部调用onUnbind,onDestroy */
特殊情况,启动服务和绑定服务的结合体
/** * > 使用场景 * * 使用startService启动一个后台服务,需要获取后台信息的时候,使activity绑定到该服务,不用的时候需要先解绑 * * > 启动服务的优先级高于绑定服务 * * 先启动服务后绑定服务,生命周期保持不变 * 先绑定服务后启动服务,生命周期变为启动服务 */
Service和Activity之间的通信(重要)
/** * Activity传递数据到Service使用Intent * Service传递数据到Activity用到Binder机制,不太好用(这里推荐使用EventBus) * * 关于EventBus视频教程 * https://ke.qq.com/course/171663#term_id=100200824 */
IntentService(推荐使用)
/** * IntentService 是继承于 Service 并处理异步请求的一个类, * 在 IntentService 内有一个工作线程来处理耗时操作, * 启动 IntentService 的方式和启动传统 Service 一样, * 同时,当任务执行完后,IntentService 会自动停止,而不需要我们去手动控制。 * 另外,可以启动 IntentService 多次, * 而每一个耗时操作会以工作队列的方式在IntentService 的 onHandleIntent 回调方法中执行, * 并且,每次只会执行一个工作线程,执行完第一个再执行第二个,以此类推。 * * 而且,所有请求都在一个单线程中,不会阻塞应用程序的主线程(UI Thread), * 同一时间只处理一个请求。 那么,用 IntentService 有什么好处呢? * 首先,我们省去了在 Service 中手动开线程的麻烦, * 第二,当操作完成时,我们不用手动停止 Service。 */
一个Demo(需要在Manifest中注册)
<application ... <service android:name=".Service.MyIntentService"/> </application>
import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.TextView; import com.example.zhangyu.myintentservice.Bean.UpdateMain; import com.example.zhangyu.myintentservice.Service.MyIntentService; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; public class MainActivity extends AppCompatActivity { private Button button; private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); EventBus.getDefault().register(this); initView(); } @Subscribe(threadMode = ThreadMode.MAIN) public void EventBusReceiver(UpdateMain updateMain) { textView.setText(updateMain.getI() + ""); } private void initView() { button = (Button) findViewById(R.id.button); textView = (TextView) findViewById(R.id.textView); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //最好用getApplicationContext Intent intent = new Intent(getApplicationContext(), MyIntentService.class); intent.putExtra("url", "https://www.baidu.com/"); startService(intent); } }); } @Override protected void onDestroy() { super.onDestroy(); if (EventBus.getDefault().isRegistered(this)) { EventBus.getDefault().unregister(this); } } }
import android.app.IntentService; import android.content.Intent; import android.support.annotation.Nullable; import android.util.Log; import com.example.zhangyu.myintentservice.Bean.UpdateMain; import org.greenrobot.eventbus.EventBus; public class MyIntentService extends IntentService { private final String TAG = "MyIntentService"; /** * Creates an IntentService. Invoked by your subclass's constructor. * * @param name Used to name the worker thread, important only for debugging. */ public MyIntentService(String name) { super(name); } public MyIntentService() { this("MyIntentServiceThread"); } @Override protected void onHandleIntent(@Nullable Intent intent) { String url = intent.getStringExtra("url"); Log.d(TAG, "onHandleIntent: " + url); // 模拟耗时操作,注意不用开启子线程 for (int i = 0; i < 5; i++) { try { Thread.sleep(1000); UpdateMain updateMain = new UpdateMain(); updateMain.setI(i); EventBus.getDefault().post(updateMain); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } Log.d(TAG, "onHandleIntent: " + Thread.currentThread().getName()); } @Override public void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy: "); } }