- linux启动过程
- 开机,确保cpu最后被复位,完成复位后,开始从固定内存地址执行第一套指令,既引导程序(Bootloader).引导程序用来装载用户程序.从CPU角度看,除了引导程序都是用户程序.
- 引导程序开始执行内核程序.内核程序初始化各种硬件.建立用于多线程和内存管理的各种内部数据结构.
- 运行home程序,home程序设 计的目标就是提供一个入口,用户可通过该入口启动其他应用.
- jni机制
java可以定义某个函数为native类型,编译器不关心此类函数的实现.运行时则要把c生成的动态库装载进来.
java调用native函数时,会自动产生一个对应的c中的函数名称,格式为,java函数的包名+java中native函数名,_作为分隔符. 例如,Java中natevi函数为 init(),则对应的c函数为 com_abc_init(JNIEnv * env,jobject clazz)
Java调用native函数时,编译器会向native引擎传递调用者包名,函数名,参数类型.native包含至少两个参数.1是JNIEnv对象,是一个Java虚拟机所运行的环境.通过它可以访问虚拟机内部对象.2是jobject对象,是调用native函数的java对象.
手工编写c代码,编译成动态库,然后在java执行时用System.loadLibrary("library name")加载动态库,就可以调用native代码了,c中的变量需要提供get,set方法才能被Java访问.
-
c调用java代码.需要把类名,函数名,参数传给java,同时,只能在java调用c函数的时候,c才能调用java函数.
1.获取java类 cls=env->GetObjectClass(jobject) env,object为c函数默认的两个参数 cls类型是jclass 2.获取函数或变量的id jmethodId mid= env->GetMethodId(cls,"method_name","([Ljava/lang/String;)V") //第二个参数为方法名,第三个括号内为参数类型,括号外为返回值类型 jfieldId fid= env->GetFiledId(cls,"filed_name","I") //参数二为变量名,参数三为变量类型 3.执行函数或获取变量值 env->CallXXXMethod(jobject,mid,ret) //执行方法 XXX标识函数返回值类型,参数三是保存返回值的变量 value= env->GetXXXFiedId(env,jobject,fid) //得到变量值XXX为变量类型,
3.classloader机制
- classloader 对象用来动态装载Class文件.classloader在初始化时必须指定Class文件路径.
- java的Runtime环境初始化时,内部会创建一个ClassLoader对象用于加载Runtime需要的各种java类
- 每个ClassLoader必须有一个父类ClassLoader,在装载类时先请求父类加载,父类加载不到时子类才会加载
- 安卓使用DexCllassLoader加载dex文件.dex文件是对class文件的优化打包.
- 异步消息机制
-
异步消息处理线程是指,线程启动后会进入一个无限循环体之中,没循环一次,从消息队列中取出一个消息,回调对应的消息处理函数,执行完则继续循环.如果消息队列为空,线程会暂停,等待消息队列有新的消息.
函数成员变量 函数内有效 类成员变量 对象内部有效 静态变量 本进程内任何对象保持一致 线程局部存储变量 本线程内任何对象保持一致 跨进程通信变量 一般用Binder定义,所有进程保持一致
- git
- 每个开发机都是一个仓库,代码可以先提交到本地仓库,在推送到远程仓库.
- 每次提交代码,都会生成一个快照,这个快照是所有被修改过的文件的一个副本.
1.git系统由提交(commit),树(tree),原文(blob)三种对象组成,每种对象都已文件方式保存,文件名为sha-1标识.
2.commit 包含所修改的文件列表,用tree表示(对象地址),作者,提交者,备注等信息.tree中列出本地提交的文件列表,包括源文件名称和文件的对象地址引用.
blob则是源文件本身.
3.每次提交都包含一个parent字段,指向上一次提交的地址,多次提交生成了一个链条.
4.一共分三个区,工作区,就是正在修改代码的区域(add前). 暂存区(staged area),git认为下次提交时应包含的区(add后,commit前).
已经提交的区(commit后`),指工作目录下的.git目录下的内容.
git branch 查看所有分支
git clone git://url local_dir 从url远程仓库克隆到本地 local_dir下
git add 提交到暂存区
git commit 提交到正式区
git checkout 分支名 切换分支
git branch [option] 分支名 新增/删除分支
git merge 分支名 合并该分支到当前所在分支.
git rebase 分支名 改变所在分支的基点到该分支最新提交.
git chery-pick 把某次提交后的状态应用到当前分支,和mrege,rebase有些相似
git reset 忽略或删除最近的某些提交,回到之前的某个提交点.
git fetch 将本地的远程分支和远程仓库的内容保值一致
git pull 将远程仓库的内容合并到本地分支
git push 将本地分支内容更新到远程仓库
-
Binder
* Binder是一种架构,包含服务端接口,Binder驱动,客户端接口.1.Binder服务端就是Binder对象,该对象内部有一个隐藏线程,接受Binder驱动发来的消息,
然后执行onTransact()函数,onTransact()函数把形参转为服务函数的参数,onTransact()函数的形参来自客户端调用transact()时输入.
2.服务端的Binder对象创建时,同时会在Binder驱动中创建一个Binder对象mRemote.客户端通过mRemote来访问远程服务.3.客户端要调用远程服务,
需要获得远程服务对应的mRemote对象,调用mRemote的transact()方法访问远程服务.客户端调用远程服务时,客户端线程会挂起,等待服务端处理完,
然后继续执行客户端代码.
- aidl,android提供了一个aidl工具来帮我们实现ipc机制.
1. 首先编写一个aidl文件
package com.bibao;
interface IMyAidlInterface { //这个接口标识服务端提供的两个方法,开始和停止.
boolean start(String FilePath);
void stop();
}
2.看系统生成的 IMyAidlInterface.java 文件,先上关系图
package com.bibao;
//IInterface 接口只有一个方法 asBinder().
public interface IMyAidlInterface extends android.os.IInterface {
/**
* Stub 是IMyAidlInterface 的内部类,Stub是一个抽象类,远程服务一般通过实现Stub类来实现 IMyAidlInterface
的具体方法.如果客户端和服务端在同一进程,可以直接调用Stub的start,stop方法.如果客户端和服务端不是统一进程,
Stub就会返回Stub的一个内部类Proxy给客户端,客户端调用Proxy的start,stop方法来调用远程服务.
Proxy的start,stop方法内部又会通过mRemote的transact方法夸进程调用Sutb的onTransact方法来真正调用远程服务的start,stop方法.
同时,mRemote的transact方法被调用时会挂起客户端线程,等待远程服务的方法执行完.
*/
public static abstract class Stub extends android.os.Binder implements com.bibao.IMyAidlInterface {
private static final java.lang.String DESCRIPTOR = "com.bibao.IMyAidlInterface"; //提供服务的标记.每个Stub的标记唯一.
/**
* Construct the stub at attach it to the interface.
*/
public Stub() {
this.attachInterface(this, DESCRIPTOR);//把当前IInterface 交给当前Binder,与下边的queryLocalInterface 对应
}
// 把IBinder 转化成远程服务IMyAidlInterface,跨进程时返回Proxy,不夸进程时返回Stub. 通常做法是我们先得到某服务的IBinder,
然后通过这个方法调用远程服务.
public static com.bibao.IMyAidlInterface asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.bibao.IMyAidlInterface))) {
return ((com.bibao.IMyAidlInterface) iin);
}
return new com.bibao.IMyAidlInterface.Stub.Proxy(obj);
}
@Override // IInterface的方法
public android.os.IBinder asBinder() {
return this;
}
//夸进程时会调用的方法,把客户端进程的数据data读出来,处理完后写入reply返回值中,此方法运行在服务端的线程中,
通过code来确定客户端要请求的方法.
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_start: {
data.enforceInterface(DESCRIPTOR); //与writeInterfaceToken对应,是一种校验方式.
java.lang.String _arg0;
_arg0 = data.readString();
boolean _result = this.start(_arg0);
reply.writeNoException();
reply.writeInt(((_result) ? (1) : (0)));
return true;
}
case TRANSACTION_stop: {
data.enforceInterface(DESCRIPTOR);
this.stop();
reply.writeNoException();
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
//跨进程通讯时客户端持有该对象,客户端调用Proxy的远程方法时,看起来像是在
调用远程服务,其实是Proxy内部调用mRemote.transact方法来调用远程方法,同时挂起客户端线程
private static class Proxy implements com.bibao.IMyAidlInterface {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
@Override
public android.os.IBinder asBinder() {
return mRemote;
}
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
@Override
public boolean start(java.lang.String FilePath) throws android.os.RemoteException {
//data 是方法接受的参数 reply是方法返回的参数 方法指服务端的方法
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(FilePath);
mRemote.transact(Stub.TRANSACTION_start, _data, _reply, 0);//远程过程调用
_reply.readException();
_result = (0 != _reply.readInt());
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override
public void stop() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
//最后一个参数 ,0表示双向,服务端有返回结果,1表示单向,服务端不返还任何数据,既_reply不保存数据
mRemote.transact(Stub.TRANSACTION_stop, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
}
//用来标识调用远程服务的哪个方法.
static final int TRANSACTION_start = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_stop = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}
public boolean start(java.lang.String FilePath) throws android.os.RemoteException;
public void stop() throws android.os.RemoteException;
}