文章目录
#AIDL的分割块逻辑#
一、安卓定义接口语言AIDL(AndroidStudio)
new===>AIDL===>AIDL File
// TestAIDL.aidl
package com.example.zbv.aidl;
import android.os.Bundle;
// Declare any non-default types here with import statements
interface TestAIDL {
void testInterface(in Bundle bundle);
}
二、实现aidl的服务类
package com.example.zbv.aidl;
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Messenger;
import android.os.RemoteException;
import android.support.annotation.Nullable;
public class TestService extends Service {
private Messenger mMessenger;
@Nullable
@Override
public IBinder onBind(Intent intent) {
mMessenger=intent.getParcelableExtra("callback");//从绑定处获取中间人
return mIBinder;
}
interface infoInterface{
/**
* 把state的状态传给客户端,至于客户端如何操作是客户端的事情
* */
void fetchActivityState(int state);
}
private infoInterface infoInterface;
public void setInfoInterface(infoInterface mInfoInterface){
infoInterface=mInfoInterface;
}
private TestAIDL.Stub mIBinder=new TestAIDL.Stub(){
@Override
public void testInterface(Bundle bundle) throws RemoteException {
String action=bundle.getString("action");
if(action.equals("ActivityState")){
int state=bundle.getInt("state");
// Toast.makeText(TestService.this,"当前的状态:"+state,Toast.LENGTH_SHORT).show();
infoInterface.fetchActivityState(state);
}
}
};
}
三、activity实现
package com.example.zbv.myapplication;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import com.example.zbv.aidl.TestAIDL;
public class MainActivity extends AppCompatActivity {
//用于处理客户端反馈的信息
private Handler mHandler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case 0:
boolean isOpen=(boolean)msg.obj;
handleEvents(isOpen);
break;
}
}
};
private TextView tv_feedback;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_feedback= (TextView) findViewById(R.id.tv_feedback);
//开启绑定服务的aidl
getTestAIDL();
}
private void getTestAIDL() {
Intent intent=new Intent();
intent.setAction("com.zbv.state");//隐式启动
// intent.setComponent(new ComponentName("服务包名","服务类全名"));
intent.putExtra("callback",new Messenger(mHandler));
bindService(intent,conn, Context.BIND_AUTO_CREATE);
}
private TestAIDL testAIDL;
private ServiceConnection conn=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d("zbv","onServiceConnected");
testAIDL=TestAIDL.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d("zbv","onServiceDisconnected");
testAIDL=null;
}
};
private void handleEvents(boolean isOpen){
if(isOpen){
tv_feedback.setText("客户选择打开");
}else{
tv_feedback.setText("客户不愿意打开");
}
}
public void sendInfo(View view){
if(testAIDL!=null){
Bundle bundle=new Bundle();
bundle.putString("action","ActivityState");
bundle.putInt("state",3);
try {
testAIDL.testInterface(bundle);
} catch (RemoteException e) {
e.printStackTrace();
}
}else{
getTestAIDL();
}
}
}
四、aidl的和服务类打成JAR包—gradle
在自己所在模块我的是Test_aidl的build.gradle中配置书写打jar包代码(在末尾添加书写即可):
task deleteOldJar(type: Delete) {
//删除存在的
delete 'build/libs/Test_aidl.jar'
}
task makeJar(type: org.gradle.api.tasks.bundling.Jar) {
//指定生成的jar名
baseName 'Test_aidl'
//从哪里打包class文件
//com/c_imageloader为包名目录
from('build/intermediates/classes/debug/com/example/zbv/aidl/')
//jar包的目录结构(文件处于com/c_imageloader目录下)
//生成的jar包没有包名
into('build/libs/')
//去掉不需要打包的目录和文件
//exclude('BuildConfig.class', 'R.class')
//去掉R$开头的文件
//exclude{ it.name.startsWith('R$');}
// include('classes.jar')
//重命名
// rename ('classes.jar', 'mysdk.jar')
}
makeJar.dependsOn(deleteOldJar, build)
//jar包默认生成在build/libs下
最后sync后点击Gradle(显示在代码窗口的侧边菜单栏),选择moduleName/Tasks/other/makeJar点击即可,有一段时间的编译打包过程,生成的jar在build/libs下
五、打包的aidl的jar包干啥用呢?
简单说明:用于第三方使用获取接口信息或者传递信息给本应用通讯,最大的用处之一就是:逻辑和显示分开(如果想供第三方使用aidl需要打一个aar包)
附上AndroidStudio中导入第三方jar包以及打jar包操作的日常记录:
Android Studio:
一、lib库文件的添加:
切换到project项目下选择需要添加的module会出现libs的文件夹,将需要的第三方jar包拷贝进去,然后快捷键F12进入Project Structure
选择菜单栏最右边的dependencies,之后点击右上角的加号添加:File Dependency选择该jar即可
二、把特定的几个java类打成jar包供第三方应用使用:
可能需要在app中的build.gradle中添加模块依赖,然后在当前module下的build.gradle中添加相应的代码。示例如下:
task deleteOldJar(type: Delete) {
//删除存在的
delete 'build/libs/Test_aidl.jar'
}
task makeJar(type: org.gradle.api.tasks.bundling.Jar) {
//指定生成的jar名
baseName 'Test_aidl'
//从哪里打包class文件
//基本都是在build文件下把class文件打包成jar
from('build/intermediates/classes/debug/com/example/zbv/aidl/')
//jar包的目录结构(文件处于com/c_imageloader目录下)
//生成的jar包没有包名
into('build/libs/')
//去掉不需要打包的目录和文件
//exclude('BuildConfig.class', 'R.class')
//去掉R$开头的文件
//exclude{ it.name.startsWith('R$');}
//include('classes.jar')
//重命名
//rename ('classes.jar', 'mysdk.jar')
}
makeJar.dependsOn(deleteOldJar, build)
//jar包默认生成在build/libs下
之后sync后点击Gradle(显示在代码窗口的侧边菜单栏),选择moduleName/Tasks/other/makeJar点击即可,有一段时间的编译打包过程,生成的jar在build/libs下
补充:aidl打包成aar供其他app调用
六、aidl打包成ARR(Android Studio)
首先:新建一个module,使用Android Library,将aidl服务工程中的AIDL文件夹拷贝至java/main下
然后build编译后在build/outputs/aar/xxxx.aar文件生成
方式一:之后新建一个module,使用import .JAR/.AAR Package,将路径引用至上面的.aar文件即可,然后编译刷新整个工程会出现单独的这个模块
之后在需要使用到的第三方App中引入上一步的.AAR模块即可
方式二:使用gradle加载aar
步骤一:在module的gradle的android中添加
repositories {
flatDir{
dirs 'libs'
}
}
步骤二:引入aar
dependencies {
implementation(name:'aidlaar-debug',ext:'aar')
}
然后编译即可
服务端
package com.telit.aidlprovider;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.QuickContactBadge;
import android.widget.Toast;
import com.telit.aidlprovider.aidl.IMyAidlInterface;
/**
* author: qzx
* Date: 2019/6/27 8:39
*/
public class ProviderService extends Service {
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 7:
/**
* Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
* */
Log.e("zbv", "Handler");
Intent intent = new Intent(ProviderService.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK );
intent.putExtra("resource", "52588");
startActivity(intent);
break;
}
}
};
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mIBinder;
}
private IMyAidlInterface.Stub mIBinder = new IMyAidlInterface.Stub() {
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
}
@Override
public void fetchResource(String resourceId) throws RemoteException {
Log.e("zbv", "fetchResource" + resourceId + "Thread=" + Thread.currentThread());
if (resourceId.equals("52588")) {
mHandler.sendEmptyMessage(7);
}
}
};
}
调用端:
package com.telit.aidlcustomer;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import com.telit.aidlprovider.aidl.IMyAidlInterface;
public class MainActivity extends AppCompatActivity {
private IMyAidlInterface myAidlInterface;
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.e("zbv", "onServiceConnected");
myAidlInterface = IMyAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e("zbv", "onServiceDisconnected");
myAidlInterface = null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void startAIDL(View view) {
/*
* android5.0之后,如果servicer不在同一个App的包中,需要设置service所在程序的包名
* */
Intent intent = new Intent();
intent.setAction("com.telit.aidlprovider.ProviderService");
intent.setPackage("com.telit.aidlprovider");
bindService(intent, conn, Service.BIND_AUTO_CREATE);
}
public void terminalAIDL(View view) {
unbindService(conn);
}
public void test(View view) {
try {
if (myAidlInterface != null) {
myAidlInterface.fetchResource("52588");
} else {
Toast.makeText(this, "aidl服务未绑定", Toast.LENGTH_SHORT).show();
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
最后追加一个微笑吧 ^ _ ^!