毕业已经有一个多月了,Android也自学了2年多了(都是晚上学一点),因为自己的木讷,不自信,最近很迷茫,再加上公司给自己的定位是Android前端开发,还有一部分C#中间层代码的编写(嘴贱说自己大学用c#做过网页-o-),工作因为同事出差很忙,让我变得很闲(不知道干啥),更让我对未来产生了很大的恐惧;于是今天就决定梳理下自己的Android知识体系,让自己认识到真实的自己,对未来不在迷茫;同时这也应该是对Android各个知识(使用?)方面的总结,我之所以分享出来也是因为这方面的考虑;这都是网上资料+我自己的感悟及补充,有什么不足的地方请指正,也请宽容(毕竟也算是新人了,哈哈-0-)! 不多说了,看正文!!!
// IMyAidlInterface.aidl
package com.example.happyghost.studytest;
// Declare any non-default types here with import statements
interface IMyAidlInterface {
/**
* 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);
}
在这个aidl文件里可以定义任何基于上面类型的方法,要想自定义类型,自定义的类型需实现Parcelable接口,下面和细节一块讲;
定义一个基本类型方法
// IMyAidlInterface.aidl
package com.example.happyghost.studytest;
// Declare any non-default types here with import statements
interface IMyAidlInterface {
String getName();
}
public class MyAidlService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new MyBind();
}
class MyBind extends IMyAidlInterface.Stub{
@Override
public String getName() throws RemoteException {
return "I am aidl in the ipc";
}
}
}
而这个服务就是自己的APP里绑定一个其他APP(其他进程)中的service
public class MainActivity extends AppCompatActivity {
private IMyAidlInterface iMyAidlInterface;
private TextView tvAidl;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//这个“com.example.happyghost.studytest.MyAidlService”是在AndroidManifest.xml中声明的Service
//的过滤意图action 具体样式如下:
/**
*
*
*
*
*
*/
Intent intent = new Intent("com.example.happyghost.studytest.MyAidlService");
//显示启动服务
//intent.setComponent(new ComponentName("com.example.happyghost.studytest", "com.example.happyghost.studytest.MyAidlService"));
//隐式启动服务===》转成显示启动服务
Intent implicitIntent = createExplicitFromImplicitIntent(this, intent);
MyAidlServiceConnection conn = new MyAidlServiceConnection();
bindService(implicitIntent,conn,BIND_AUTO_CREATE);
tvAidl = (TextView) findViewById(R.id.aidl);
tvAidl.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
tvAidl.setText(iMyAidlInterface.getName());
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
private class MyAidlServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
public static Intent createExplicitFromImplicitIntent(Context context, Intent implicitIntent) {
//检索所有的服务,以匹配给定的意图
PackageManager pm = context.getPackageManager();
List resolveInfo = pm.queryIntentServices(implicitIntent, 0);
//确保只进来一次
if (resolveInfo == null || resolveInfo.size() != 1) {
return null;
}
//获取组件信息并创建ComponentName
ResolveInfo serviceInfo = resolveInfo.get(0);
String packageName = serviceInfo.serviceInfo.packageName;
String className = serviceInfo.serviceInfo.name;
ComponentName component = new ComponentName(packageName, className);
//创建一个新的目的
Intent explicitIntent = new Intent(implicitIntent);
//将组件设置为显式
explicitIntent.setComponent(component);
return explicitIntent;
}
}
注意:在这里有个坑,在5.0系统以下,隐式,显式开启服务都可以,但是在5.0系统以上隐式开启服务会让程序崩溃掉,具体有原因请看这篇博客。所以我们需要用工具方法createExplicitFromImplicitIntent()将隐式意图转成显式意图,代码中有详细的注释;
看结果:
public class Student implements Parcelable{
String name;
int age;
public Student(){}
public Student(Parcel in) {
name = in.readString();
age = in.readInt();
}
public static final Creator CREATOR = new Creator() {
@Override
public Student createFromParcel(Parcel in) {
return new Student(in);
}
@Override
public Student[] newArray(int size) {
return new Student[size];
}
};
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
}
}
注意:如果你在原始目录下又新建了一个包,而自定义类型放在了这个包中,你需要在AIDL文件原始目录下同样需要建一个包名相同的包,看下图:
// Student.aidl
package com.example.happyghost.studytest.aidldemo;
// Declare any non-default types here with import statements
parcelable Student ;
// IMyAidlInterface.aidl
package com.example.happyghost.studytest;
// Declare any non-default types here with import statements
import com.example.happyghost.studytest.aidldemo.Student;
interface IMyAidlInterface {
List getStudent();
void addStudent(in Student student);
}
记得每次修改aidl文件需要同步一下。。。。
public class MyAidlService extends Service {
private List mStudents = new ArrayList();
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new MyBind();
}
@Override
public void onCreate() {
super.onCreate();
Student student = new Student();
for (int i = 0; i < 10; i++) {
student.setName("xiao ming"+i);
student.setAge(10+i);
mStudents.add(student);
}
}
class MyBind extends IMyAidlInterface.Stub{
@Override
public List getStudent() throws RemoteException {
return mStudents;
}
@Override
public void addStudent(Student student) throws RemoteException {
mStudents.add(student);
}
}
}
tvAidl.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
List<com.example.happyghost.studytest.aidldemo.Student> student = iMyAidlInterface.getStudent();
Student student1 = student.get(0);
tvAidl.setText(student1.getName()+"\n"+"\r"+student1.getAge());
// tvAidl.setText(iMyAidlInterface.getName());
} catch (RemoteException e) {
e.printStackTrace();
}
}
});