Android -Services 使用简介
Posted zCoderJoy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android -Services 使用简介相关的知识,希望对你有一定的参考价值。
android Services 四大组件之一,主要用于后台长时间运行。没有界面。这里讲解两种services的启动还有AIDL通信方式。
1.startservices
a.建立继承services的类,复写方法(本地服务)
public class MyServices extends Service { private static final String TAG="TestTag"; @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub return null; } @Override public void onCreate() { Log.i(TAG, "onCreate"); super.onCreate(); } @Override public void onStart(Intent intent, int startId) { Log.i(TAG, "onStart"); super.onStart(intent, startId); } @Override public void onDestroy() { Log.i(TAG, "onDestroy"); super.onDestroy(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i(TAG, "onStartCommand"); return super.onStartCommand(intent, flags, startId); } }
b.声明AndroidManifest
<service android:name=".MyServices"/>
c.启动关闭
switch(v.getId()){ case R.id.btnStart: startService(intent); break; case R.id.btnStop: stopService(intent); break; }
后记:
服务生命周期:context.startService() ->onCreate()- >onStart()- >onStartCommand()->Service running ->context.stopService() ->onDestroy() ->Service stop
如果Service还没有运行,则android先调用onCreate()然后调用onStartCommand(),每次调用startService(Intent)的时候,都会调用执行onStartCommand();
如果Service已经运行,则只调用onStartCommand()。
2.bindservices
服务链接(ServiceConnection)或直接获取Service中状态和数据信息
服务链接能够获取Service的对象,因此绑定Service的组件可以调用Service中的实现的函数
使用Service的组件通过Context.bindService()建立服务链接,通过Context.unbindService()停止服务链接
如果在绑定过程中Service没有启动,Context.bindService()会自动启动Service
同一个Service可以绑定多个服务链接,这样可以同时为多个不同的组件提供服务
a.创建BindService继承Service
public class BindService extends Service { private static final String TAG="BindService"; private BindServiceX myBinderServiceX=new BindServiceX(); public class BindServiceX extends Binder{ public BindService getBindService() { return BindService.this; } } @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub Log.i(TAG, "onBind"); return myBinderServiceX; } @Override public void onCreate() { Log.i(TAG, "onCreate"); super.onCreate(); } @Override public boolean onUnbind(Intent intent) { Log.i(TAG, "onUnbind"); return super.onUnbind(intent); } @Override public void onDestroy() { Log.i(TAG, "onDestroy"); super.onDestroy(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i(TAG, "onStartCommand"); return super.onStartCommand(intent, flags, startId); } public void ShowLog(){ Log.i(TAG, "BindService=>ShowLog"); } }
b.声明AndroidManifest
<service android:name=".BindService"/>
c.启动使用
public void onClick(View v) { Intent intentBind = new Intent(MainActivity.this, BindService.class); switch (v.getId()) { case R.id.btnStartBindService: bindService(intentBind, conn, Context.BIND_AUTO_CREATE); break; case R.id.btnStopBindService: if (isConn) { unbindService(conn); //不可以多次调用 isConn=false; } break; }
后记:
AndroidServiceActivity绑定方法,Context.BIND_AUTO_CREATE表明只要绑定存在,就自动建立Service;同时也告知Android系统,这个Service的重要程度与调用者相同,除非考虑终止调用者,否则不要关闭这个Service。
如果service没被创建,那么调用一次onCreate(),然后调用onBind(),多次绑定时,不会多次调用onBind()。
通过unbindService()函数取消绑定Servcie时,onUnbind()函数将被调用,
如果onUnbind()函数的返回true,则表示在调用者绑定新服务时,
onRebind()函数将被调用
取消绑定仅需要使用unbindService()方法,并将ServiceConnnection传递给unbindService()方法需注意的是,unbindService()方法成功后,系统并不会调用onServiceDisconnected(),因为onServiceDisconnected()仅在意外断开绑定时才被调用
3.AIDL IPC通信 services
Android系统中,各个应用都运行在自己的进程中,进程之间一般无法直接进行通信,为了实现进程通信(interprocess communication,简称IPC),android提供了AIDL Service;
Android需要AIDL(Android Interface Definition Language)来定义远程接口,这种接口定义语言并不是一种真正的变成语言,只是定义两个进程之间的通信接口;
与Java接口相似,但是存在如下几点差异:
-
AIDL定义接口的源代码必须以.aidl结尾;
-
AIDL用到的数据类型,除了基本类型、String、List、Map、CharSequence之外,其它类型全部都需要导包,即使它们在同一个包中也需要导包;
AIDL的步骤:
a.创建AIDL文件
package com.example.zcx.servicesdemo; // Declare any non-default types here with import statements //interface ICat { // /** // * Demonstrates some basic types that you can use as parameters // * and return values in AIDL. // */ // void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, // double aDouble, String aString); //} interface ICat { String getColor(); double getWeight(); }
b.服务端编写
public class AidlService extends Service { String[] colors = new String[] { "红色", "黄色", "黑色" }; double[] weights = new double[] { 2.3, 3.1, 1.58 }; private String color; private double weight; private CatBinder catBinder; Timer timer = new Timer(); @Override public void onCreate() { super.onCreate(); catBinder = new CatBinder(); timer.schedule(new TimerTask() { @Override public void run() { // 随机地改变service组件内的color,weight属性的值 int rand = (int) (Math.random() * 3); color = colors[rand]; weight = weights[rand]; System.out.println("---------" + rand); } }, 0, 800); } @Override public IBinder onBind(Intent arg0) { /** * 返回CatBinder对象,在绑定本地Service情况下, * 该catBinder会直接传给客户端的ServiceConnected对象的ServiceConnected * ()方法的第二个参数;在绑定远程Service的情况下 * ,只将catBinder对象的代理传给客户端的ServiceConnected对象的ServiceConnected()方法的第二个参数 */ return catBinder; } @Override public void onDestroy() { timer.cancel(); } /** * 继承Stub,也就是实现了ICat接口,并实现了IBinder接口 * * @author pengcx * */ public class CatBinder extends ICat.Stub { @Override public String getColor() throws RemoteException { return color; } @Override public double getWeight() throws RemoteException { return weight; } } }
androidmanifest:
<service android:name=".AidlService" android:process=":remote"> <intent-filter> <action android:name="org.crazyit.aidl.AIDL_SERVICE" /> </intent-filter> </service>
c.客户端使用
首先需要建立aidl,注意要在相同的包名下,否则报错: java.lang.SecurityException: Binder invocation to an incorrect interface
// ICat.aidl package com.example.zcx.servicesdemo; // Declare any non-default types here with import statements //interface ICat { // /** // * Demonstrates some basic types that you can use as parameters // * and return values in AIDL. // */ // void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, // double aDouble, String aString); //} interface ICat { String getColor(); double getWeight(); }
编写客户端:
public class MainActivity extends AppCompatActivity { private ICat catService; private Button getButton; private EditText colorEditText, weightEditText; private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { catService = null; } @Override public void onServiceConnected(ComponentName name, IBinder service) { // 获取远程Service的onBinder方法返回的对象代理 catService = ICat.Stub.asInterface(service); Log.d("zcx","catService"); } }; public static Intent getExplicitIntent(Context context, Intent implicitIntent) { // Retrieve all services that can match the given intent PackageManager pm = context.getPackageManager(); List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0); // Make sure only one match was found if (resolveInfo == null || resolveInfo.size() != 1) { return null; } // Get component info and create ComponentName ResolveInfo serviceInfo = resolveInfo.get(0); String packageName = serviceInfo.serviceInfo.packageName; String className = serviceInfo.serviceInfo.name; ComponentName component = new ComponentName(packageName, className); // Create a new intent. Use the old one for extras and such reuse Intent explicitIntent = new Intent(implicitIntent); // Set the component to be explicit explicitIntent.setComponent(component); return explicitIntent; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getButton = (Button) findViewById(R.id.getbutton); colorEditText = (EditText) findViewById(R.id.coloredittext); weightEditText = (EditText) findViewById(R.id.weightedittext); // 创建所需要绑定的Service的Intent Intent intent = new Intent(); intent.setAction("org.crazyit.aidl.AIDL_SERVICE"); //intent.setPackage(getPackageName()); Intent eintent = new Intent(getExplicitIntent(this,intent)); Log.e("zcx","eintent = "+eintent); // 绑定远程的服务 Log.e("zcx"," "+bindService(eintent, conn, Service.BIND_AUTO_CREATE)); getButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 获取并显示远程service的状态 try { colorEditText.setText(catService.getColor()); weightEditText.setText(catService.getWeight() + ""); } catch (RemoteException e) { e.printStackTrace(); } } }); } @Override protected void onDestroy() { super.onDestroy(); // 解除绑定 this.unbindService(conn); } }
以上是关于Android -Services 使用简介的主要内容,如果未能解决你的问题,请参考以下文章
我的Android进阶之旅Android Studio 中 使用git提交代码报错:Can‘t commit changes from multiple changelists at once(代码片
Android 逆向ART 脱壳 ( InMemoryDexClassLoader 脱壳 | BaseDexClassLoader 构造函数 | DexPathList 构造函数及后续调用 )(代码片
FlutterFlutter 全面屏适配 ( 需要适配的情况 | Android 设置最大宽高比 | 使用 SafeArea 进行全面屏适配 | 使用 MediaQuery 进行全面屏适配 )(代码片
Android Studio编译OsmAnd出现警告:GeoPointParserUtil.java使用或覆盖了已过时的 API。有关详细信息请使用-Xlint:deprecation重新编译(代码片
Android 逆向修改运行中的 Android 进程的内存数据 ( 运行环境搭建 Android 模拟器安装 | 拷贝 Android 平台可执行文件和动态库到 /data/system )(代码片