因为最近要面试,于是打算整理整理一下Android的基础知识,由于之前本人已经学习过大概的Android基础知识,这里主要讲这四大组件、五大存储、六大布局、网络请求等这些内容,其他一些等有时间再整理,话不多说。
应用组件(官方解释,需科学上网)
应用组件是 Android 应用的基本构建基块。每个组件都是一个不同的点,系统可以通过它进入您的应用。 并非所有组件都是用户的实际入口点,有些组件相互依赖,但每个组件都以独立实体形式存在,并发挥特定作用 — 每个组件都是唯一的构建基块,有助于定义应用的总体行为。
共有四种不同的应用组件类型。每种类型都服务于不同的目的,并且具有定义组件的创建和销毁方式的不同生命周期。
一、什么是Service(服务)?
从官方的解释中可以看到:
Service
服务是一种在后台运行的组件,用于执行长时间运行的操作或为远程进程执行作业。 服务不提供用户界面。 例如,当用户位于其他应用中时,服务可能在后台播放音乐或者通过网络获取数据,但不会阻断用户与 Activity 的交互。 诸如 Activity 等其他组件可以启动服务,让其运行或与其绑定以便与其进行交互。
参考网站:https://www.jianshu.com/p/d963c55c3ab9 https://www.jianshu.com/p/95ec2a23f300
Service是Android系统中的四大组件之一,主要有两个应用场景:后台运行和跨进程访问。Service可以在后台执行长时间运行操作而不提供用户界面,除非系统必须回收内存资源,否则系统不会停止或销毁服务。服务可由其他应用组件启动,而且即使用户切换到其他应用,服务仍然将在后台继承运行。此外,组件还可以绑定到服务,然后与服务进行交互,甚至是执行进程间通信(IPC)。
注:Service是在主线程里执行操作的,可能会因为执行耗时操作而导致ANR(Application Not Responding),即无响应。
- 定义:服务是Android四大组件之一,属于计算型组件。
- 作用:提供需在后台长时间运行的服务(如:复杂计算、音乐播放、下载等等)
- 特点:在后台运行、生命周期长、无用户界面
二、Service(服务)的生命周期
2.1 生命周期的常用方法
- 官方说明图:
在Service的生命周期里,常用的有:
- 4个手动调用的方法,如下
手动调用方法 作用 startService() 启动服务 stopService() 关闭服务 bindService() 绑定服务 unbindService() 解绑服务
- 5个自动调用的方法,如下
内部自动调用的方法 作用 onCreate() 创建服务 oStartCommand() 开始服务 onBind() 绑定服务 onUnbind() 解绑服务 onDestroy() 销毁服务 2.2 生命周期方法的具体介绍
2.3 常用的生命周期使用
三、Service(服务)的类型
3.1 具体分类
Service可按照地点、运行类型、功能进行分类,具体如下:
- 地点
1.本地服务
2.远程服务
- 运行类型
1.前台服务
2.后台服务
- 功能
1.可通信服务
2.不可通信服务
示意图如下:
3.2 详细介绍
四、Service(服务)各种类型的使用
- 本地服务(LocalService)
1.介绍
这是最普通、最常用的后台服务Service。
2.使用步骤
(1)新建子类继承Service类(需重写父类的onCreate()、onStartCommand()、onDestroy()、onBind()方法)
(2)构建用来启动Service的Intent对象
(3)调用startService()启动Service、调用stopService()停止服务
(4)在AndroidMinifest.xml里注册Service
3.代码示例
(1)activity_main.xml
(2)MyService类
public class MyService extends Service { private static final String TAG = "MyService"; public MyService() { } @Override public void onCreate() { super.onCreate(); Log.d(TAG, "onCreate: "); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG, "onStartCommand: "); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { Log.d(TAG, "onDestroy: "); super.onDestroy(); } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } }
(3)MainActivity类
public class MainActivity extends AppCompatActivity implements View.OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button1 = findViewById(R.id.button1); Button button2 = findViewById(R.id.button2); button1.setOnClickListener(this); button2.setOnClickListener(this); } @Override public void onClick(View v) { Intent intent = new Intent(getApplicationContext(), MyService.class); switch (v.getId()) { case R.id.button1: startService(intent); break; case R.id.button2: stopService(intent); break; } } }
(4)AndroidManifest.xml清单文件
Androidmanifest里Service的常见属性说明
属性 说明 备注 android:name Service的类名 android:label Service的名字 若不设置,默认为Service类名 android:icon Service的图标 android:permission 申明此Service的权限 有提供了该权限的应用才能控制或连接此服务 android:process 表示该服务是否在另一个进程中运行(远程服务) 不设置默认为本地服务;remote则设置成远程服务 android:enabled 系统默认启动 true:Service 将会默认被系统启动;不设置则默认为false android:exported 该服务是否能够被其他应用程序所控制或连接 不设置默认此项为 false 4.运行结果
05-01 17:18:00.777 22569-22569/com.peterli.localservicetest D/MyService: onCreate: 05-01 17:18:00.777 22569-22569/com.peterli.localservicetest D/MyService: onStartCommand: 05-01 17:18:11.827 22569-22569/com.peterli.localservicetest D/MyService: onDestroy:
- 远程服务(RemoteService)
1.介绍(远程服务与本地服务的区别)
远程服务与本地服务最大的区别是:远程服务与调用者不再同一个进程里(也就是说远程服务是运行在另外一个进程); 而本地服务则是与调用者运行在同一个进程里
示意图如下:
2.使用场景
多个应用程序共享同一个后台远程服务。(也就是说一个远程服务与多个应用程序的组件(四大组件)进行跨进程通信)
示意图:
3.具体使用
3.1 前言
为了让远程Service与多个应用程序的组件(四大组件)进行IPC(跨进程通信),需要使用AIDL(Android接口定义语言)
(1)IPC:Inter-Process Communication,即跨进程通信。
(2)AIDL:Android Interface Definition Language,即Android接口定义语言;用于让某个Service与多个应用程序组件之 间进行跨进程通信,从而可以实现多个应用程序共享同一个Service的功能。
在多进程通信中,存在两个进程角色(以最简单的为例):服务器端和客户端
3.2 使用步骤
服务器端(Service)
(1)新建定义AIDL文件,并声明该服务需要向客户端提供的接口
(2)在Service子类中实现AIDL中定义的接口方法,并定义生命周期的方法(onCrate、onBind、onDestroy等等)
(3)在AndroidManifest.xml中注册服务和声明为远程服务
客户端(Client)
(1)拷贝服务器端的AIDL文件到目录下
(2)使用Stud.asInterface接口获取服务器的Binder,根据需要调用服务提供的接口方法
(3)通过Intent指定服务端的服务名称和所在包,绑定远程Service
3.3 代码示例
服务器端(Service)工程项目:
步骤1: 新建一个AIDL文件(懒得截图,使用原网站的图)
步骤2:在新建AIDL文件里定义Service需要与Activity进行通信的内容(方法),并进行编译(Make Project)
// 在新建的AIDL_Service1.aidl里声明需要与Activity进行通信的方法 package scut.carson_ho.demo_service; interface AIDL_Service1 { void AIDL_Service(); } //AIDL中支持以下的数据类型 //1. 基本数据类型 //2. String 和CharSequence //3. List 和 Map ,List和Map 对象的元素必须是AIDL支持的数据类型; //4. AIDL自动生成的接口(需要导入-import) //5. 实现android.os.Parcelable 接口的类(需要导入-import)
步骤3:在Service子类中实现AIDL中定义的接口方法,并定义生命周期的方法(onCreat、onBind()等等)
public class MyService extends Service { private static final String TAG = "MyService"; private AIDL_Service1.Stub mBinder = new AIDL_Service1.Stub() { @Override public void AIDL_Service() throws RemoteException { Log.d(TAG, "AIDL_Service: 客户端通过AIDL与远程后台成功通信"); } }; public MyService() { } @Override public void onCreate() { super.onCreate(); Log.d(TAG, "onCreate: "); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG, "onStartCommand: "); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { Log.d(TAG, "onDestroy: "); super.onDestroy(); } @Override public IBinder onBind(Intent intent) { Log.d(TAG, "onBind: "); return mBinder; } @Override public boolean onUnbind(Intent intent) { Log.d(TAG, "onUnbind: "); return super.onUnbind(intent); } }
步骤4:在AndroidMainfest.xml中注册服务 & 声明为远程服务
//该Service可以响应带有scut.carson_ho.service_server.AIDL_Service1这个action的Intent。 //此处Intent的action必须写成“服务器端包名.aidl文件名” 客户端(Client)工程项目:
步骤1:将服务端的AIDL文件所在的包复制到客户端目录下(Project/app/src/main),并进行编译。(懒得截图,使用原网站的图)
PS:记得要原封不动地复制!!什么都不要改!
步骤2:在主布局文件定义按钮
步骤3:在MainActivity.java里
- 使用Stub.asInterface接口获取服务器的Binder;
- 通过Intent指定服务端的服务名称和所在包,进行Service绑定;
- 根据需要调用服务提供的接口方法。
public class MainActivity extends AppCompatActivity { //定义aidl接口变量 private AIDL_Service1 mAIDL_service; //创建ServiceConnection的匿名类 private ServiceConnection mServiceConnection = new ServiceConnection() { //在Activity与Service建立关联时调用 @Override public void onServiceConnected(ComponentName name, IBinder service) { //使用AIDLService1.Stub.asInterface()方法获取服务器端返回的IBinder对象 //将IBinder对象传换成了mAIDL_Service接口对象 mAIDL_service = AIDL_Service1.Stub.asInterface(service); try { //通过该对象调用在MyAIDLService.aidl文件中定义的接口方法,从而实现跨进程通信 mAIDL_service.AIDL_Service(); } catch (RemoteException e) { e.printStackTrace(); } } //重写onServiceConnected()方法和onServiceDisconnected()方法 //在Activity与Service建立关联和解除关联的时候调用 @Override public void onServiceDisconnected(ComponentName name) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button1 = findViewById(R.id.button1); Button button2 = findViewById(R.id.button2); Button button3 = findViewById(R.id.button3); Button button4 = findViewById(R.id.button4); button1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //通过Intent指定服务端的服务名称和所在包,与远程Service进行绑定 //参数与服务器端的action要一致,即"服务器包名.aidl接口文件名" Intent intent = new Intent("com.peterli.remoteserviceserver.AIDL_Service1"); //Android5.0后无法只通过隐式Intent绑定远程Service //需要通过setPackage()方法指定包名 intent.setPackage("com.peterli.remoteserviceserver"); //绑定服务,传入intent和ServiceConnection对象 bindService(intent, mServiceConnection, BIND_AUTO_CREATE); } }); button2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { unbindService(mServiceConnection); } }); button3.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent("com.peterli.remoteserviceserver.AIDL_Service1"); intent.setPackage("com.peterli.remoteserviceserver"); startService(intent); } }); button4.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent("com.peterli.remoteserviceserver.AIDL_Service1"); intent.setPackage("com.peterli.remoteserviceserver"); stopService(intent); } }); } }
3.4 运行结果(按的顺序:开启服务-->绑定服务-->解绑服务-->停止服务)
05-01 20:51:10.329 29345-29345/com.peterli.remoteserviceserver:remote D/MyService: onCreate: 05-01 20:51:10.329 29345-29345/com.peterli.remoteserviceserver:remote D/MyService: onStartCommand: 05-01 20:51:12.879 29345-29345/com.peterli.remoteserviceserver:remote D/MyService: onBind: 05-01 20:51:12.879 29345-29357/com.peterli.remoteserviceserver:remote D/MyService: AIDL_Service: 客户端通过AIDL与远程后台成功通信 05-01 20:51:17.239 29345-29345/com.peterli.remoteserviceserver:remote D/MyService: onUnbind: 05-01 20:51:19.269 29345-29345/com.peterli.remoteserviceserver:remote D/MyService: onDestroy:
从上面测试结果可以看出:
- 打印的语句分别运行在不同进程(看语句前面的包名);
- 客户端调用了服务端Service的方法
(即客户端和服务端进行了跨进程通信)
- 后台服务
几乎服务都是在后台运行的,以本地后台为例,那个就是普通的后台服务。
- 前台服务
1. 介绍
服务几乎都是在后台运行的,但后台服务的系统优先级还是比较低的,但系统出现内存不足的情况时,就有可能会回收掉正在后台运行的服务。如果想要服务一直保持运行状态,不被系统回收,就可以考虑使用前台服务。前台服务和后台服务最大的区别就在于,它会有一个正在运行的图标在系统状态栏显示,下拉状态栏后可以看到更加详细的信息,非常类似于通知的效果。或者说可能你并不是希望服务不被系统回收,而是有其他特殊的需求(比如天气APP数据的服务)。
2. 代码示例
用法很简单,只需要在原有的Service类对onCreate()方法进行稍微修改即可,本人亲测与是否可通信服务无关,如下:
8.0以下:
@Override public void onCreate() { super.onCreate(); System.out.println("执行了onCreat()"); //添加下列代码将后台Service变成前台Service //构建"点击通知后打开MainActivity"的Intent对象 Intent notificationIntent = new Intent(this,MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this,0,notificationIntent,0); //新建Builer对象 Notification.Builder builer = new Notification.Builder(this); builer.setContentTitle("前台服务通知的标题");//设置通知的标题 builer.setContentText("前台服务通知的内容");//设置通知的内容 builer.setSmallIcon(R.mipmap.ic_launcher);//设置通知的图标 builer.setContentIntent(pendingIntent);//设置点击通知后的操作 Notification notification = builer.getNotification();//将Builder对象转变成普通的notification startForeground(1, notification);//让Service变成前台Service,并在系统的状态栏显示出来 }
8.0以上:
@Override public void onCreate() { super.onCreate(); Log.d(TAG, "onCreate: "); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); String channelId = getString(R.string.app_name); NotificationChannel notificationChannel = new NotificationChannel(channelId, channelId, NotificationManager.IMPORTANCE_DEFAULT); notificationChannel.setDescription(channelId); notificationChannel.setSound(null, null); notificationManager.createNotificationChannel(notificationChannel); Intent intent = new Intent(getApplicationContext(), MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0); Notification.Builder builder = new Notification.Builder(this, channelId); builder.setContentTitle("这是一个标题"); builder.setContentText("这是一个内容"); builder.setSmallIcon(R.mipmap.ic_launcher); builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher)); builder.setContentIntent(pendingIntent); Notification notification = builder.build(); startForeground(1, notification); }
3. 测试结果(本人还是懒得截图,贴上原网站的图片)
运行后,当点击Start Service或Bind Service按钮,Service就会以前台Service的模式启动(通知栏上有通知),如下图
- 可通信的后台服务
1. 介绍
普通的本地后台服务是最基础的,但只能单机使用,即无法与Activity通接下来将在上面的基础用法上,增设“与Activity通 信”的功能,即使用绑定Service服务(Binder类、bindService()、onBind()、unbindService()、onUnbind())
2. 使用步骤
(1)在新建子类继承Service类,并新建一个子类继承自Binder类、写入与Activity关联需要的方法、创建实例。
(2)在主布局文件再设置两个Button分别用于绑定和解绑Service。
(3)在Activity通过调用MyBinder类中的public方法来实现Activity与Service的联系。
(即实现了Activity指挥Service干什么Service就去干什么的功能)
3. 代码示例
MyService类
public class MyService extends Service { private static final String TAG = "MyService"; private MyBinder mBinder = new MyBinder(); public MyService() { } class MyBinder extends Binder{ public void serviceConnectActivity(){ Log.d(TAG, "Service关联了Activity,并在Activity执行了Service的方法"); } } @Override public void onCreate() { super.onCreate(); Log.d(TAG, "onCreate: "); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG, "onStartCommand: "); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { Log.d(TAG, "onDestroy: "); super.onDestroy(); } @Override public IBinder onBind(Intent intent) { Log.d(TAG, "onBind: "); return mBinder; } @Override public boolean onUnbind(Intent intent) { Log.d(TAG, "onUnbind: "); return super.onUnbind(intent); } }
activity_main.xml
MainActivity类
public class MainActivity extends AppCompatActivity implements View.OnClickListener { private MyService.MyBinder mMyBinder; private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mMyBinder = (MyService.MyBinder) service; mMyBinder.serviceConnectActivity(); } @Override public void onServiceDisconnected(ComponentName name) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button1 = findViewById(R.id.button1); Button button2 = findViewById(R.id.button2); Button button3 = findViewById(R.id.button3); Button button4 = findViewById(R.id.button4); button1.setOnClickListener(this); button2.setOnClickListener(this); button3.setOnClickListener(this); button4.setOnClickListener(this); } @Override public void onClick(View v) { Intent intent = new Intent(getApplicationContext(), MyService.class); switch (v.getId()) { case R.id.button1: startService(intent); break; case R.id.button2: stopService(intent); break; case R.id.button3: bindService(intent, mServiceConnection, BIND_AUTO_CREATE); break; case R.id.button4: unbindService(mServiceConnection); break; } } }
3.4 运行结果(按的顺序:开启服务-->绑定服务-->解绑服务-->停止服务):
05-01 23:29:07.025 2373-2373/com.peterli.communicationservice D/MyService: onCreate: 05-01 23:29:07.025 2373-2373/com.peterli.communicationservice D/MyService: onStartCommand: 05-01 23:29:10.075 2373-2373/com.peterli.communicationservice D/MyService: onBind: 05-01 23:29:10.105 2373-2373/com.peterli.communicationservice D/MyService: Service关联了Activity,并在Activity执行了Service的方法 05-01 23:29:13.845 2373-2373/com.peterli.communicationservice D/MyService: onUnbind: 05-01 23:29:14.875 2373-2373/com.peterli.communicationservice D/MyService: onDestroy:
- 不可通信的后台服务
以本地后台为例,那个就是普通的不可通信后台服务,它并没有与其他组件进行通信。
五、Service(服务)各种类型的使用场景
- 各种Service的使用场景请看下图:
六、IntentService的使用及其工作原理
1.定义
IntentService是Android里的一个封装类,继承四大组件之一的Service。
2.作用
处理异步请求和实现多线程,它可以简单地创建一个异步的、会自动停止的服务。
3.使用场景
线程任务需按顺序、在后台执行
1.最常见的场景:离线下载
2.不符合多个数据同时请求的场景:所有的任务都在同一个Thread looper里执行
4.工作原理
4.1 流程示意图
IntentService的工作原理和源码工作流程如下:
4.2 特别注意
如果启动IntentsService多次,那么每个耗时操作则是以队列的方式在IntentsService的onHandleIntent回调方法中依 次执行,执行完自动结束。
5.源码分析
问题1:IntentService如何单独开启1个新的工作线程(主要从源码中的onCreate方法入手)
@Override public void onCreate() { super.onCreate(); // 1. 通过实例化HandlerThread新建线程 & 启动;故 使用IntentService时,不需额外新建线程 // HandlerThread继承自Thread,内部封装了 Looper HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start(); // 2. 获得工作线程的 Looper & 维护自己的工作队列 mServiceLooper = thread.getLooper(); // 3. 新建mServiceHandler & 绑定上述获得Looper // 新建的Handler 属于工作线程 ->>分析1 mServiceHandler = new ServiceHandler(mServiceLooper); } /** * 分析1:ServiceHandler源码分析 **/ private final class ServiceHandler extends Handler { // 构造函数 public ServiceHandler(Looper looper) { super(looper); } // IntentService的handleMessage()把接收的消息交给onHandleIntent()处理 @Override public void handleMessage(Message msg) { // onHandleIntent 方法在工作线程中执行 // onHandleIntent() = 抽象方法,使用时需重写 ->>分析2 onHandleIntent((Intent)msg.obj); // 执行完调用 stopSelf() 结束服务 stopSelf(msg.arg1); } } /** * 分析2: onHandleIntent()源码分析 * onHandleIntent() = 抽象方法,使用时需重写 **/ @WorkerThread protected abstract void onHandleIntent(Intent intent);
问题2:IntentService如何通过onStartCommand() 将Intent传递给服务还有依次插入到工作队列中
/** * onStartCommand()源码分析 * onHandleIntent() = 抽象方法,使用时需重写 **/ public int onStartCommand(Intent intent, int flags, int startId) { // 调用onStart()->>分析1 onStart(intent, startId); return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; } /** * 分析1:onStart(intent, startId) **/ public void onStart(Intent intent, int startId) { // 1. 获得ServiceHandler消息的引用 Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; // 2. 把 Intent参数 包装到 message 的 obj 发送消息中, //这里的Intent = 启动服务时startService(Intent) 里传入的 Intent msg.obj = intent; // 3. 发送消息,即 添加到消息队列里 mServiceHandler.sendMessage(msg); }
6.源码总结
从上面源码可以看出:IntentService本质 = Handler + HandlerThread:
1. 通过HandlerThread单独开启1个工作线程(子线程):IntentService
2. 创建1个内部Handler:ServiceHandler
3. 绑定ServiceHandler与IntentService
4. 通过onStartCommand()传递服务intent到ServiceHandler、依次插入Intent到工作队列中并且逐个发送给 onHandleIntent()
5. 通过onHandleIntent()依次处理所有Intent对象所对应的任务
(因此我们通过重写onHandleIntent()在里面根据Intent的不同进行不同线程操作即可)
7.注意事项
此处,有两个注意事项需要关注的:
1. 工作任务队列 = 顺序执行
2. 不建议通过bindService()启动IntentService
注意事项1:工作任务队列 = 顺序执行
解释:
即如果一个任务正在IntentService中执行,此时你再发送1个新的任务请求,这个新的任务会一直等待直到前面一个任务执行完毕后才开始执行。
原因:
1. 由于onCreate()只会调用一次,所以它只会创建1个工作线程(子线程);
2. 当多次调用startService()时(即onStartCommand()也会调用多次),其实不会创建新的工作线程,只是把消息加入消 息队列中等待执行;
3. 所以,多次启动IntentService会按照顺序执行事件(若服务停止,则会清除消息队列中的消息,后续的事件不再执行)
注意事项2:不建议通过bindService()启动IntentService
原因:
// 在IntentService中,onBind()默认返回null @Override @Nullable public IBinder onBind(Intent intent) { return null; }
- 采用bindService()启动IntentService的生命周期如下:
onCreate() -->onBind() --> onUnbind() --> onDestory()
- 由上面生命周期可以得知不会调用onStart()或onStartCommand(),故不会将消息发送到消息队列,那么也就是说onHandleIntent()也将不会回调,即无法实现多线程的操作(所以,此时你应该使用Service,而不是IntentService)
七、IntentService与Service(服务)、Thread(普通线程)的区别
此处主要讲解IntentService与Service(服务)、Thread(普通线程)的区别。
1. IntentService与Service(服务)的区别
2. IntentService与Thread(普通线程)的区别
八、Service(服务)与Thread(线程)的区别
- 结论:Service与Thread无任何关系!!!
- 之所以会有不少人把他们联系起来,主要是因为Service的后台概念(后台:后台任务运行完全不依赖UI,即时活动被销毁或者说程序被关闭,只要进程还在,后台任务就可以继续运行)
- 关于二者的异同,具体如下图:
- 注:一般会将Service和Thread联合着用,即在Service中再创建一个子线程(工作线程)去处理耗时操作逻辑,如下代码:
@Override public int onStartCommand(Intent intent, int flags, int startId) { //新建工作线程 new Thread(new Runnable() { @Override public void run() { // 开始执行后台任务 } }).start(); return super.onStartCommand(intent, flags, startId); } class MyBinder extends Binder { public void service_connect_Activity() { //新建工作线程 new Thread(new Runnable() { @Override public void run() { // 执行具体的下载任务 } }).start(); } }