最近又学习了下service,对service又多了一些了解和认识。温故而知新,这话果然没错,现在趁热打铁,赶紧记下来。
- service定义:
Service是android四大组件之一,主要用于在后台处理一些耗时的逻辑,或者去执行某些需要长期运行的任务。必要的时候我们甚至可以在程序退出的情况下,让Service在后台继续保持运行状态。而Service是运行在主线程里的,如果直接在Service中处理一些耗时的逻辑,就会导致程序ANR,所以需要另外开启子线程来处理。 - 基本用法:
新建MyService继承自Service;
在MainActivity中启动和停止Service代码如下:Intent startservice = new Intent(this, MyService.class);
startService(startservice);//启动
Intent stopIntent = new Intent(this, MyService.class);
stopService(stopIntent); //停止
不要忘了在AndroidManifest.xml中注册
MyService Service启动后如果没有StopService操作即使activity被销毁任然会在后台运行 - Service和activity通信:
任何一个Service在整个应用程序范围内可以和任何一个Activity(通信)建立关联
Start service 和 Stop service相对应
Bind service 和unbind service相对应,在activity中是成对出现
启动并绑定service后,想销毁service,必须有停止和解绑两个执行操作,单独某一个都不能销毁service
*注意 当activity与service绑定后退出activity或销毁activity后activity与service绑定关系解除,可能程序还会报错,所以有必要在activity的onDestory()方法内调用unbindService()解除绑定
下面是简单的测试service生命周期代码:
service类代码:
类中包含一继承service就必须实现的onBind()和重写了的onCreate()、 onStartCommand() 、onStart()、onDestroy()方法。activity与service就是通过onBind()来进行连接,具体操作看下面代码。
注意看方法中的注释、Log和I的赋值
public class MyService extends Service {
public static final String TAG = "MyService";
public int I = 0;
/*activity与service绑定时会调用*/
public IBinder onBind(Intent intent) {
I = 10;
Log.e(TAG, "ooo----------onBind() " + " getI==" + I);
return new MyBinder();
}
/*第一次创建时才会调用,之后在服务没被销毁都不会调用 ,创建*/
public void onCreate() {
super.onCreate();
I = 1;
Log.e(TAG, "ooo----------onCreate() " + " getI==" + I);
}
/*第一次创建时和以后每次启动都会调用,重建*/
public int onStartCommand(Intent intent, int flags, int startId) {
I = 2;
Log.e(TAG, "ooo----------onStartCommand() " + "getI==" + I);
// Log.e(TAG, "eee----------onStartCommand() "+intent+" " + "getI=="+I +" "+ flags +"第"+startId+"次启动");
return super.onStartCommand(intent, flags, startId);
}
/*和onStartCommand()方法一样每次都会调用,启动*/
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
I=3;
Log.e(TAG, "ooo----------onStart() " + "getI==" + I);
}
/*销毁时调用*/
public void onDestroy() {
super.onDestroy();
I = 4;
Log.e(TAG, "ooo----------onDestroy() " + " getI==" + I);
}
public class MyBinder extends Binder {
MyService getService() {
return MyService.this;
}
}
public int getI() {
return I;
}
}
布局文件servict_layout
<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/service_start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="启动" />
<Button
android:id="@+id/service_stop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="停止" />
<Button
android:id="@+id/service_bind"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="绑定" />
<Button
android:id="@+id/service_unbind"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="解除" />
<Button
android:id="@+id/show_oclick_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="getI" />
<TextView
android:id="@+id/show_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="0" />
</LinearLayout>
Mainactivity类:
public class MAinActivity extends Activity implements View.OnClickListener {
private Button Start, Stop, Bind, UnBind, showbtn;
private TextView showtext;
private MyService.MyBinder myBinder;
private MyService mService;
boolean mBound = false;
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.servict_layout);
Start = (Button) findViewById(R.id.service_start);
Stop = (Button) findViewById(R.id.service_stop);
Bind = (Button) findViewById(R.id.service_bind);
UnBind = (Button) findViewById(R.id.service_unbind);
showbtn = (Button) findViewById(R.id.show_oclick_btn);
showtext = (TextView) findViewById(R.id.show_text);
Start.setOnClickListener(this);
Stop.setOnClickListener(this);
Bind.setOnClickListener(this);
UnBind.setOnClickListener(this);
showbtn.setOnClickListener(this);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.service_start://启动服务
Intent startservice = new Intent(this, MyService.class);
startService(startservice);
Log.e("MAinActivity", "----------start button getI=" + showI());
showI();
Toast.makeText(this, "start", Toast.LENGTH_SHORT).show();
break;
case R.id.service_stop://停止服务
Intent stopservice = new Intent(this, MyService.class);
stopService(stopservice);
Log.e("MAinActivity", "----------stop button getI=" + showI());
showI();
Toast.makeText(this, "stop", Toast.LENGTH_SHORT).show();
break;
case R.id.service_bind://绑定服务
Intent bindservice = new Intent(this, MyService.class);
bindService(bindservice, connection, BIND_AUTO_CREATE);
Log.e("MAinActivity", "----------bind button getI=" + showI());
showI();
Toast.makeText(this, "bind", Toast.LENGTH_SHORT).show();
break;
case R.id.service_unbind://解除绑定
Log.e("MAinActivity", "----------Unbind button getI=" + showI());
if (mBound) {
unbindService(connection);
mBound = false;
}
showI();
Toast.makeText(this, "unbind", Toast.LENGTH_SHORT).show();
break;
case R.id.show_oclick_btn://
show();//获取后台I的值(没有绑定服务I显示为null)
Log.e("MAinActivity", "----------show button getI=" + showI());
break;
case R.id.button:
Intent intent = new Intent(this, OtherActivity.class);
startActivity(intent);
break;
}
}
public String showI() {
if (mService != null) {
//showtext.setText(mService.getI() + "");
return mService.getI() + "";
} else {
// showtext.setText("null");
return "null";
}
}
public void show() {
if (mService != null) {
showtext.setText(mService.getI() + "");
} else {
showtext.setText("null");
}
}
//实例服务连接接口
public ServiceConnection connection = new ServiceConnection() {
//连接成功回调
public void onServiceConnected(ComponentName name, IBinder service) {
myBinder = (MyService.MyBinder) service;
mService = myBinder.getService();
mBound = true;
}
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onDestroy() {
super.onDestroy();
/* if (mBound) {
unbindService(connection);//这里注释了,当activity被销毁,绑定依然会解除,程序可能还会报错
mBound = false;
}*/
}
}
贴完代码下面开始讲述我测试的过程:
运行程序之后的界面
依次点击 绑定、getI、启动、getI、解除、getI、停止 、getI按钮打印日志如下:
当我没启动service就让activity与service绑定(关联),service会执行onCreate()方法再执行onBind()方法,然后点击getI得到I为10,之后再启动服务service先后执行了onStartCommand()、onStart()方法点击getI得到I为3,当我点击解除关联,再getI依然可以得到I的值3,接着点击停止服务后,这时服务已经销毁service执行了onDestroy()方法,再次点击getI得到I值为4。这时就有问题了,为什么绑定解除了且service已经销毁了,activity任能获取service中方法执行结果?这里我的理解是绑定解除或service已经销毁activity是不能再获取service中的方法的,因为service是运行在主线程那么就是和activity在同一个UI线程里,在每一次执行后I的值会缓存在UI线程里。
本人初出茅庐,才疏学浅,正努力积累经验中。。。
如有不足和错误观点,欢迎指出纠正。