Android Service 线程
来源:互联网 发布:淘宝店铺复核秒过技术 编辑:程序博客网 时间:2024/04/30 10:57
Service 与线程的区别?
1.首先Service是Android系统提供的组件,用于执行一些“无界面”的任务;线程则是操作系统或者Java语言的概念,可以开启一个线程用于执行一系列任务,两者不在一 个层面。
2.在Android中,每一个App至少对应一个进程,在该进程中有且必有一个线程是主线程,也称UI线程,由于UI线程涉及到App的运行界面绘制,所以不允许堵塞,在一个 App进程中,允许开启子线程完成一些耗时操作。
3.Service默认运行在主线程也就是UI线程,所以Service默认情况下也是不能做耗时操作的,当有需要在Service中做耗时操作时,可以在Service中开启子线程完成。
Service 与线程如何选择?
Service的优先级高于后台挂起的Activity,当然,也高于Activity所创建的Thread,因此,系统可能在内存不足的时候优先杀死后台的Activity或者Thread,而不会轻易杀 死Service组件,即使被迫杀死Service,也会在资源可用时重启被杀死的Service。
线程可以在Activity Service 和Application中开启,并且在跟随这三者的生命周期销毁线程以防止内存泄漏,一般情况下生命周期Activity < Service < = Application。 所以可以根据运行任务的需要在Activity Service 和Application中开启子线程以执行任务。
在Service中创建子线程会更灵活,不用care Activity 是否被销毁,别的activity也可以跟Service灵活绑定,执行相应的任务。
定义一个Service
public class MyService extends Service { public static final String TAG = "MyService"; private MyBinder mBinder = new MyBinder(); @Override public void onCreate() { super.onCreate(); Log.d(TAG, "onCreate() executed"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG, "onStartCommand() executed"); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy() executed"); } @Override public IBinder onBind(Intent intent) { return mBinder; } class MyBinder extends Binder { public void startDownload() { Log.d("TAG", "startDownload() executed"); // 执行具体的下载任务 } } }在onBind()方法中返回了一个MyBinder的对象,这个对象会在Activity 调用bindService的时候,传入的ServiceConnection对象的回调onService()方法里以参数的形式返回:Activity中定义:
private MyService.MyBinder myBinder;
private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) { myBinder = (MyService.MyBinder) service; myBinder.startDownload(); } };Activity中执行:
Intent bindIntent = new Intent(this, MyService.class); bindService(bindIntent, connection, BIND_AUTO_CREATE);
任何一个Service在整个应用程序范围内都是通用的,即MyService不仅可以和MainActivity建立关联,还可以和任何一个Activity建立关联,而且在建立关联时它们都可以获取到相同的MyBinder实例。
执行StopService只会让Service停止,执行Unbind Service只会让Service和Activity解除关联,一个Service必须要在既没有和任何Activity关联又处理停止状态的时候才会被销毁。
前台Service
如果你希望Service可以一直保持运行状态,而不会由于系统内存不足的原因导致被回收,就可以考虑使用前台Service。 Notification notification = new Notification(R.drawable.ic_launcher, "有通知到来", System.currentTimeMillis()); Intent notificationIntent = new Intent(this, MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); notification.setLatestEventInfo(this, "这是通知的标题", "这是通知的内容", pendingIntent); startForeground(1, notification);
首先创建一个Notification对象,然后调用了它的setLatestEventInfo()方法来为通知初始化布局和数据,并在这里设置了点击通知后就打开MainActivity。然后调用startForeground()方法就可以让MyService变成一个前台Service,并会将通知的图片显示出来。
远程Service将一个普通的Service转换成远程Service其实非常简单,只需要在注册Service的时候将它的android:process属性指定成:remote
<service android:name="com.example.servicetest.MyService" android:process=":remote" > </service>
远程Service会在新的进程中运行,不会阻塞当前App进程的UI线程。
远程Service中 bindService会失效,需要使用AIDL进行绑定。
AIDL
新建一个aidl文件,他是interface类型的:
package com.example.servicetest; interface MyAIDLService { int plus(int a, int b); String toUpperCase(String str); }建完后build工程,开发环境会自动根据这个interface生成对应的同名java类,该类中有一个比较重要的内部类Stub:MyAIDLService.Stub:
MyAIDLService.Stub mBinder = new Stub() { @Override public String toUpperCase(String str) throws RemoteException { if (str != null) { return str.toUpperCase(); } return null; } @Override public int plus(int a, int b) throws RemoteException { return a + b; } };可以利用他生成一个Binder对象,并实现aidl接口中定义的方法,并在Service的onBind()方法中返回该对象。
远程(另外一个进程的)Activity就可以bindService了:
private MyAIDLService myAIDLService;
private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) { myAIDLService = MyAIDLService.Stub.asInterface(service); try { int result = myAIDLService.plus(3, 5); String upperStr = myAIDLService.toUpperCase("hello world"); Log.d("TAG", "result is " + result); Log.d("TAG", "upperStr is " + upperStr); } catch (RemoteException e) { e.printStackTrace(); } } };
这个Stub类有一个比较重要的方法asInterface(),可以将connect的IBinder参数抓换成aidl文件对应类的对象,利用这个对象,可以调用aidl中定义的方法,而这些方法的实现,在Service的进程中。在这个过程中,比较蛋疼的是:两个进程必须都拥有aidl文件,这个文件甚至是两份同名的包.类名称aidl文件。
- Android Service 线程问题
- Android Service 线程问题
- Android Service 线程问题
- Android Service 线程
- android中service与线程
- Android-Service通知与线程
- Android Service介绍(Service与线程关系)
- 关于android中service与线程
- Android平台调用Web Service:引入线程
- android系统service组件的线程关系
- Android0909<十四>(Service、Android线程)
- Service IntentService Android中的线程 MediaPlayer
- android service与子线程之浅谈
- android service和线程的用法区别
- Android Service跟线程及IntentService使用
- Android service 不是进程也不是线程
- Android中Activity、Service和线程之间的通信
- Android中Activity、Service和线程之间的通信
- Java中堆内存和栈内存详解
- Android Study Material Design 八 之 玩转Palette调色板
- 联想电脑安装虚拟机出现不可恢复的错误
- C语言练习11.12
- 常见15个C语言的标准库
- Android Service 线程
- 并发工具类(二)同步屏障CyclicBarrier
- Retrofit2.0
- android锁屏唤醒并解锁屏幕
- [NOIP2017]蒟蒻翻车记
- matlab自带的分类器的使用实例
- Comparator long类型的比较bug实录
- 飞机调度,白书P325LA3211(2-SAT算法, 二分查找“最小值尽量大”)
- MySQL事务初识