前言:
我们都知道Android的四大基本组件:Activity、ContentProvider、Service以及BroadcastReceiver,前面的两个我们在前几篇已经具体讲解了,今天这一天我们就把后两者的使用具体说一下,由于Service和BroadcastReceiver常常一起使用,所以我们一起来学习。
一.Service的使用
Service是Android系统的后台服务组件,没有用户界面,但可以长时间的运行,比Activity的优先级高,可以用于进程间的通信。
Service也同Activity一样有自己的生命周期,但是Service有两种生命周期,也就是Service由两种启动以及对应的停止方式:
1.以启动方式使用的Service:
(1)特点:
A.通过Content.startService()启动,Content.stopService()或者Content.stopSelf()来停止;
(即只能通过其他组件启动,但可以自己停止)
B.不能与外部的组件进行交互;
(2)生命周期:
onCreate——>onStartCommand——>onDestroy
(3)示例代码:L0828_Service(记得注册)
MyService.java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.example.l0828_service;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class MyService extends Service{
//声明定时器,用于创建新的进程来计时
private Timer timer;
private TimerTask task;
private static int i=0;
//继承Service必须要重写的方法onBind
@Override
public IBinder onBind(Intent intent) {
return null;
}
/*Service的生命周期一:onCreate、onStartCommand、onDestroy方法构成*/
//onCreate方法,启动服务,每次启动仅仅调用一次
@Override
public void onCreate() {
System.out.println("onCreate");
super.onCreate();
}
//onStartCommand方法,一般在其中完成Service的工作
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("onStartCommond");
startTimer();
return super.onStartCommand(intent, flags, startId);
}
//onDestroy方法,用来释放Service的资源
@Override
public void onDestroy() {
System.out.println("onDestroy");
stopTimer();
super.onDestroy();
}
//开启定时器
public void startTimer(){
timer =new Timer();
task=new TimerTask(){
@Override
public void run() {
i++;
System.out.println(i);
}
};
timer.schedule(task, 1000, 1000);
}
//停止定时器
public void stopTimer(){
timer.cancel();
}
}
Mainactivity.java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.example.l0828_service;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener{
private Button btn_start,btn_stop;
//声明Intent用于Activity向Service的跳转
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_start=(Button) findViewById(R.id.btn_start);
btn_stop=(Button) findViewById(R.id.btn_stop);
btn_start.setOnClickListener(this);
btn_stop.setOnClickListener(this);
//Activity组件向Service组件的跳转
intent=new Intent(MainActivity.this,MyService.class);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_start:
//开启服务
startService(intent);
break;
case R.id.btn_stop:
//停止服务
stopService(intent);
break;
}
}
}
主配置文件.xml文件中注册:
1
运行效果:
起始界面
[11.JPG]
点击开始——停止的过程显示:
[12.JPG]
停止之后再次点击开始按钮又重新执行onCreate方法:
[13.JPG]
2.以绑定方式使用的Service:
(1)特点:
A.通过Content.bindService()绑定而建立与服务器的连接,通过Content.unbindService()方法解除绑定从而断开与服务器的连接;
B.如果没有调用startService直接通过调用bindService绑定服务器也会自动启动服务器;
C.能获得Service的对象,从而能够使得其他组件与Service的交互;
D.同一个Service可以绑定多个服务连接,同时与不同的组件交互;
(2)生命周期:
onCreate——>onBind——>onCommand——>onUnbind——>onRebind——>onDestroy
如果onUnbind方法返回true,则当取消绑定之后重写绑定服务时就直接调用onRebind方法了。
(3)示例代码:
MyService.java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package com.example.l0828_service2;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
public class MyService extends Service{
private Timer timer;
private TimerTask task;
private int i=0;
private int j=0;
//创建内部类,用于创建Binder对象,onBinder方法中使用
class MyBinder extends Binder{
public MyService getService(){
return MyService.this;
}
}
private MyBinder binder=new MyBinder();
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
public int getJ() {
return j;
}
public void setJ(int j) {
this.j = j;
}
//下面分别重写Service生命周期的方法
@Override
public IBinder onBind(Intent intent) {
//绑定服务,开始于界面交互
startTimer();
System.out.println("onBind");
return binder;
}
@Override
public void onCreate() {
System.out.println("onCreate");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public boolean onUnbind(Intent intent) {
//解除与服务器的绑定,停止与界面的交互
stopTimer();
System.out.println("onUnbind");
//为了使onRebind能够调用到,使得onUnbind的返回值为true
super.onDestroy();
return true;
}
@Override
public void onRebind(Intent intent) {
System.out.println("onRebind");
super.onRebind(intent);
}
@Override
public void onDestroy() {
System.out.println("onDestroy");
}
//创建定时器,即创建另一个线程负责计时
public void startTimer(){
timer=new Timer();
task=new TimerTask() {
@Override
public void run() {
i++;
if(i==j){
System.out.println("此时您输入的数据于服务数据相同:"+j);
}
System.out.println(i);
}
};
timer.schedule(task, 1000,1000);
}
//停止计时
public void stopTimer(){
timer.cancel();
}
}
MainActivity.java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package com.example.l0828_service2;
import com.example.l0828_service2.MyService.MyBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener,ServiceConnection{
private Button btn_bind,btn_unBind,btn_getService,btn_start,btn_stop;
private Intent intent;
private MyService myservice;
private EditText et;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et=(EditText) findViewById(R.id.et);
btn_bind=(Button) findViewById(R.id.btn_bind);
btn_unBind=(Button) findViewById(R.id.btn_unBind);
btn_getService=(Button) findViewById(R.id.btn_getService);
btn_start=(Button) findViewById(R.id.btn_start);
btn_stop=(Button) findViewById(R.id.btn_stop);
btn_bind.setOnClickListener(this);
btn_unBind.setOnClickListener(this);
btn_getService.setOnClickListener(this);
btn_start.setOnClickListener(this);
btn_stop.setOnClickListener(this);
intent=new Intent(MainActivity.this, MyService.class);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_bind:
bindService(intent, this, BIND_AUTO_CREATE);
break;
case R.id.btn_unBind:
unbindService(this);
break;
case R.id.btn_getService:
String info=et.getText().toString();
if("".equals(info)){
Toast.makeText(MainActivity.this,"当前的i值:"+myservice.getI() , Toast.LENGTH_SHORT).show();
}
myservice.setJ(Integer.parseInt(info));
break;
case R.id.btn_start:
startService(intent);
break;
case R.id.btn_stop:
stopService(intent);
break;
}
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MyService.MyBinder binder=(MyBinder) service;
myservice=binder.getService();
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
运行效果:
初始界面:
[21.JPG]
依次点击start、bind、unbind、输入一个服务还未计时到的数、getService、stop的过程:
[22.JPG]
下图是上面执行过程的输出情况,可以清晰明了的看出整个执行的过程:
[23.JPG]
下面是这样的执行顺序的结果:
start、bind、输入及时数据、getService、unbind、(正是此时调用了onRebind方法)bind、unbind、stop的过程
[24.JPG]
二.BroadcastReceiver的使用
1.使用广播实现简单的数据接收功能:
(1)MainActivity.java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.example.l0829_broadcastreceiver;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btn_send).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//仍然是使用Intent来实现组件之间的跳转
Intent intent=new Intent(MainActivity.this, MyBroadCastReceiver.class);
//把要向广播接收器发送的数据用Intent对象封装,注意键值要相同
intent.putExtra("name", "我接收到了");
//发送数据
sendBroadcast(intent);
}
});
}
}
(2)MyBroadcastReceiver.java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.example.l0829_broadcastreceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
//继承BroadcastReceiver
public class MyBroadCastReceiver extends BroadcastReceiver{
//只需重写OnReceiver方法
@Override
public void onReceive(Context context, Intent intent) {
//接收特定键值的数据,实现广播接收器的基本功能
String str=intent.getStringExtra("name");
System.out.println(str);
}
}
(3)一定不要忘记注册啊(四大基本组件是都需要在主配置文件中注册的):
1
2.再实现一个系统默认广播的例子——电量改变的广播:
(1)MainActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.example.l0829_system_broadcastreceiver;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends Activity {
//创建一个广播的实例,在其onReceive方法中实现接收的过程
private BroadcastReceiver myBR=new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
//if(Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction()))这里也可以先判断一下,确保正确性
//下面就是接收系统当前电量信息的过程,注意这里的键值level和scale是系统固定值,不能改变
int level=intent.getIntExtra("level", 0);
int scale=intent.getIntExtra("scale", 100);
tv.setText("当前电量:"+level*100/scale+"%");
}
};
//声明一个TextView用来显示接受的当前电量值
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv=(TextView) findViewById(R.id.tv_receive);
//动态注册广播的方法,在onCreate方法中
registerReceiver(myBR, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
@Override
protected void onStop() {
//在onStop方法中取消广播的注册
unregisterReceiver(myBR);
super.onStop();
}
}
(2)由于在代码中实现了Receiver的动态注册,那么主配置文件中就不用注册了
(3)运行效果:(有点小哈,凑合看看吧)
(另外有一个温馨提示:模拟器的电量值永远是50%,可以用真机测试)
[41.JPG]
3.最后算是来个总结吧:
我们实现一个Activity、Service、BroadcastReceiver三大组件结合使用的例子,完成Service始终在后台计时、BroadcastReceiver接收数据并及时更新主Activity的过程:
(1)MyService.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package com.example.l0829_zujian_all;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class MyService extends Service{
private Timer timer;
private TimerTask task;
private int i=0;
private Intent intent;
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
@Override
public void onCreate() {
//开始服务
startTimer();
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
@Override
public void onRebind(Intent intent) {
super.onRebind(intent);
}
@Override
public void onDestroy() {
//停止服务
stopTimer();
super.onDestroy();
}
public void startTimer(){
timer=new Timer();
task=new TimerTask() {
@Override
public void run() {
i++;
//在计时器中及时向ACTION_MY的BroadcastReceiver接收器中发送键值为id的数据
intent=new Intent();
intent.setAction("ACTION_MY");
intent.putExtra("id", i);
sendBroadcast(intent);
}
};
timer.schedule(task, 500,1000);
}
public void stopTimer(){
timer.cancel();
}
}
(2)MainActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package com.example.l0829_zujian_all;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener{
//创建接收器对象,并在onReceive方法中接收键值为id的数据
private BroadcastReceiver br=new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int val=intent.getIntExtra("id", 0);
System.out.println(intent.getIntExtra("id", 0));
tv_show.setText(val+"");
}
};
private Button btn_start,btn_stop;
private TextView tv_show;
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_show=(TextView) findViewById(R.id.tv_show);
btn_start=(Button) findViewById(R.id.btn_start);
btn_stop=(Button) findViewById(R.id.btn_stop);
btn_start.setOnClickListener(this);
btn_stop.setOnClickListener(this);
intent=new Intent(MainActivity.this, MyService.class);
//接收器的动态注册,Action必须与Service中的Action一致
registerReceiver(br, new IntentFilter("ACTION_MY"));
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_start:
startService(intent);
break;
case R.id.btn_stop:
stopService(intent);
break;
}
}
@Override
protected void onDestroy() {
//取接收器的消注册
unregisterReceiver(br);
super.onDestroy();
}
}
(3)注册Service,而BroadcastReceiver就不用再注册了
(4)运行效果:
[51.JPG]
[52.JPG]
即一个计时更新主页面的功能,在以后的Android应用开发的过程中,常常会用到,学会了吗?
加油!
阅读(1588) | 评论(0) | 转发(0) |