Android学习-四大组件(Service)
来源:互联网 发布:mac 文件夹隐藏与显示 编辑:程序博客网 时间:2024/06/16 18:00
今天复习Service,包括如何启动并结束一个服务、自定义服务、IntentService、活动与服务之间的通信、前台服务、异步处理以及书上写的一个无线循环的服务实践。
根据四大组件的特性,每定义一个新的服务,都要在AndroidManifest里面进行注册
<service android:name=".MyService"/>
自定义服务
自定义服务继承Service,然后可以重写里面的方法来实现逻辑
public class MyService extends Service{ @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub Log.d("myservice", "onBind执行"); return null; }}
onBind()是父类中的抽象方法,必须实现。之后就是常见的onCreate,onStartCommand,onDestroy了
onCreate可以执行一些初始化的操作,只有在活动被创建的时候调用
onStartCommand执行主要的逻辑
onDestroy用来收尾
@Overridepublic void onCreate() { // TODO Auto-generated method stub Log.d("myservice", "onCreate执行"); super.onCreate();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub Log.d("myservice", "onStartCommand执行"); return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() { // TODO Auto-generated method stub Log.d("myservice", "onDestory执行"); super.onDestroy();}
启动和停止服务
在MainActivity中实现按钮操作即可
case R.id.start_service: Intent startService=new Intent(this,MyService.class); startService(startService); break;case R.id.stop_service: Intent stopService=new Intent(this,MyService.class); stopService(stopService); break;
IntentService
IntentService可以在活动执行一次后自动结束,新建一个IntentService,并在MainActivity中绑定一个按钮,按钮点击事件同时打印MainActivity的线程id
public class MyIntentService extends IntentService{ public MyIntentService() { super("MyIntentService"); // TODO Auto-generated constructor stub } @Override protected void onHandleIntent(Intent intent) { // TODO Auto-generated method stub Log.d("myservice", "this thread id"+Thread.currentThread().getId()); } @Override public void onDestroy() { // TODO Auto-generated method stub Log.d("myservice", "intentService destroy"); super.onDestroy(); }}
MainActivity中的点击事件
case R.id.start_intentservice: Intent intentService=new Intent(this,MyIntentService.class); Log.d("myservice", "main thread id"+Thread.currentThread().getId()); startService(intentService); break;
log
服务和活动之间的通信
利用之前新建自定义活动的时候实现的onBind()函数,可以让服务与活动间进行通信
private MyBinder binder=new MyBinder();//新建MyBinder的对象 class MyBinder extends Binder{//自定义内部类继承Binder,在里面用来实现自己需要的逻辑,比如这里的下载和返回下载进度 public void startDownload() { Log.d("myservice", "startDownload"); } public int downloadProgress() { Log.d("myservice", "downloadProgress"); return 0; } } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub Log.d("myservice", "onBind执行"); return binder;//返回自定义类对象 }
在活动中,利用ServiceConnection类来执行之前在Service中的自定义类里的方法
private MyService.MyBinder mybinder;private ServiceConnection connection=new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub } @Override public void onServiceConnected(ComponentName name, IBinder service) {//绑定后会执行里面的操作 // TODO Auto-generated method stub mybinder=(MyService.MyBinder)service;//向下转型 mybinder.startDownload(); int i=mybinder.downloadProgress(); Log.d("myservice", ""+i); } };
然后在按钮事件中通过bindService和unbindService来绑定和取消绑定服务
case R.id.bind_service: Intent bindService=new Intent(this,MyService.class); bindService(bindService, connection, BIND_AUTO_CREATE);//标志位,传入BIND_AUTO_CREATE表示在活动和服务进行绑定后自动创建服务 break; case R.id.unbind_service: unbindService(connection); break;
前台服务
比后台服务多一个正在运行的图标在状态栏里面,可以直接在onCreate里面写入一个Notification
@SuppressLint("NewApi") @Override public void onCreate() { // TODO Auto-generated method stub Notification.Builder nBuilder=new Notification.Builder(this); Intent intent=new Intent(this,Activity02.class); PendingIntent pIntent=PendingIntent.getActivity(this, 0, intent, 0); nBuilder.setTicker("前台通知来了") .setContentTitle("前台通知") .setContentText("这是一个前台通知") .setContentIntent(pIntent) .setSmallIcon(R.drawable.ic_launcher); startForeground(1, nBuilder.build()); Log.d("myservice", "onCreate执行"); super.onCreate(); }
一个Notification必须具备以下几个元素,不然不能显示
1.setSmallIcon
2.setContentText
3.setContentTitle
这样,服务启动的时候就可以自动创建一个前台通知一直在通知栏里
异步消息处理
Android不允许在子线程中进行UI的操作,所以可以通过异步消息处理来进行UI的操作
新建一个CHANGE参数用来识别操作,新建一个Handler用来操作UI
private Handler handler=new Handler(){ public void handleMessage(Message msg) { switch (msg.what) { case CHANGE: textView.setText("Text02"); break; default: break; } } };
因为这个是在主线程中的,所以可以对UI进行操作,然后用子线程通过发送Message来让handler执行对应的操作,从而起到改变UI的效果
case R.id.change_text: new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub Message message=new Message(); message.what=CHANGE; handler.sendMessage(message); } }).start();//别忘了start break;
start在最后面,有时候容易忽略而忘记启动线程,这里要注意一下
后台定时循环操作
整体的实现思路是
自定义服务-onStartCommand里执行需要的操作(比如打印此时的时间),然后利用AlarmManager来执行定时操作,操作中利用广播在广播接收器中再次打开服务
public class AlarmBroadcast extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub Intent intent2=new Intent(context,AlarmService.class); context.startService(intent2); }}
注意这里是Context
AlarmManager使用方法
1.新建AlarmManager类
2.定义执行的时间
3.AlarmManager.set()执行操作
public class AlarmService extends Service{ @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } @Override public void onCreate() { // TODO Auto-generated method stub Log.d("myservice", "Alarm onCreate"); super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub Log.d("myservice", "Time is "+new Date().toString()); } }).start();//记得start AlarmManager alarmManager=(AlarmManager) getSystemService(ALARM_SERVICE); long triggerTime=SystemClock.elapsedRealtime()+30*1000;//获取开机以来的毫秒数+30秒 Intent intent2=new Intent(this,AlarmBroadcast.class); PendingIntent pIntent=PendingIntent.getBroadcast(this, 0, intent2, 0);//此处应调用getBroadcast /* * 下面第一个参数表示类型,此处的表示任务执行时间为从开机时间算起之后多少多少毫秒 * 这里就是上面的triggerTime * 并且唤醒CPU */ alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerTime, pIntent); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { // TODO Auto-generated method stub Log.d("myservice", "Alarm onDestroy"); super.onDestroy(); }}
AlarmManager.set()中第一个参数表示执行操作的模式,一共有4中,分别是ELAPSED_REALTIME、ELAPSED_REALTIME_WAKEUP、RTC和RTC_WAKEUP,他们的作用如下
第二个参数表示以第一个参数为参考,操作执行的延迟时间,比如这里第一个参数是ELAPSED_REALTIME_WAKEUP,延迟时间为SystemClock.elapsedRealtime()+30*1000毫秒,SystemClock.elapsedRealtime()用来获取开机以后到现在为止的毫秒数,所以这里的意思就是说,以开机时间为起点,操作在(已开机的时间+30秒)后执行
第三个参数就是PendingIntent,即要执行的操作,这里因为是要调用广播接收器,所以用的是getBroadcast而不是getActivity
执行结果
- Android学习-四大组件(Service)
- 【android学习】四大组件-Service
- 【android学习】四大组件-Service
- Android 学习之四大组件(二)——service
- Android四大组件之Service服务学习笔记(一)
- android学习笔记(二)四大组件Service详解
- android学习笔记(二)四大组件Service详解
- Android学习--四大组件之一 : Service(一)
- Android学习--四大组件之一 : Service(二)
- Android学习笔记--四大组件之Service
- Android 四大组件学习之Service二
- Android 四大组件学习之Service三
- Android 四大组件学习之Service四
- Android 四大组件学习之Service五
- Android 四大组件学习之Service六
- Android 四大组件学习之Service七
- Android 四大组件学习之 Service 服务
- Android学习笔记四大组件之Service
- eclipse 和android studio 导入github项目
- Struts2 数据封装机制
- patch bonding: don't use stale speed and duplex information解释
- invalid project specified
- **meaven+springmvc 开发**
- Android学习-四大组件(Service)
- ContentProvider是如何实现数据共享的。
- 工作中常用工具
- 不读书、不吃苦,你要青春干嘛
- Android-->反编译初探(mac环境配置)
- PostgreSQL亚洲活动日将于3/17--19在新加坡举行
- cuda shared memory 静态分配和动态分配
- IOS各种调试技巧(条件断点、僵尸模式、内存检测、图层透视图模式)
- 百度贴吧/V2EX站点自动签到程序