Service
/**
* 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中注册)
Demo下载地址:https://gitee.com/olleh/MyIntentService
<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: ");
}
}