android aidl使用 android-ide
Android是怎样打包apk的
} catch (Exception e) {1.)生成k}}eystore
android aidl使用 android-ide
android aidl使用 android-ide
按照下面的命令行 在C:Program FilesJajdk1.6.0_10bin>目录下,输入keytool -genkey -alias android.keystore -keyalg RSA -validity 100000 -keystore android.keystore
参数意义:-validity主要是证书的有效期,写100000天;空格,退格键 都算密码。
命令行下生成android.keystore
2.)eclipse生成apk文件
选择要打包的项目,右键点击–>Android tools–>Export Signed Application Package…eclipse 打包工具
接下来的步骤就是不断的next。下面仅贴出,不解释。
step 2:选择打包的项目
step 3: 选择生成的android.keystore文件并输入密码
step 4:选择alias key并输入密码
step 5:选择生成android apk文件的目录及文件名
最终生成的apk文件
流程概述:
1、打包资源文件,生成R.ja文件
2、处理aidl文件,生成相应ja 文件
3、编译工程源代码,生成相应class 文件
4、转换所有class文件,生成classes.dex文件
5、打包生成apk
6、对apk文件进行签名
7、对签名后的apk文件进行对其处理
Android中怎么启动关闭Serv及功能解释
上图中,我的serv下配置了intent-filter标签,按理说intent-filter标签下还应该有action子标签,比如像下图这样的标准写法:是指代码实现吗?
一般分两种
startServ()->stopSelf()/stopServlist = new ArrayList
bindServ()->onUnBind();
建议看开发文档有相关说明,找个例子练习下,很简单的。
1、 Serv不是分离开的进程,除非其他特殊情况,它不会运行在自己的进程,而是作为启动运行它的进程的一部分。
android软件开发的架构
LOCAL_BUILT_MODULE_STEM := libyfcdca.aAndroid以Ja为编程语言,使接口到功能,都有层出不穷的变化,其中Activity等同于J2ME的MIDlet,一个 Activity 类(class)负责创建视窗(window),一个活动中的Activity就是在 foreground(前景)模式,背景运行的程序叫做Serv。两者之间通过由全部画面被其他ServConnection和AIDL连结,达到复数程序同时运行的效果。如果运行中的 Activity 全部画面被其他 Activity 取代时,该 Activity 便被停止(stopped),甚至被系统清除(kill)。
android怎么与pc上的进程进行rpc通信
理解Android系统的进程间通信原理(二)----RPC机制
理解Android系统中的轻量级解决方案RPC的原理,需要先回顾一下JAVA中的RMI(Remote Mod Invocation)这个易于使用的纯JAVA方案(用来实现分布式应用)。有关RMI的相关知识,可以通过下图来归纳:
RMI原理 (2然后按提示作就可以在工程目录下生成mContext = context;一个build.gradle文件,之后我们就可以用AndroidStudio导入这个build.gradle文件了,导入的过程中会连同这个工程一齐导入,之后,就会看到导入后的工程了,如图所示:)
Android中的RPC也是参考了JAVA中的RMI方案,这里我们再详细了解一下RPC的实现过程。
Android中的RPC机制是为了实现一个进程使用另一个进程中的远程对象,它使用了Android自己的AIDL(接口定义语言),使用户很方便地定义出一个接口作为规范,通过一个远程Serv为 ,客户端在绑定该远程Serv过程中获取远程对象,进而使用该对象。可参考下图所示:
Android的RPC原理及应用 (2)
补充:RPC的另一个目的是对客户端只声明接口及方法,隐藏掉具体实现类,供客户端直接获取此接口实例。
实例代码:
实例一:通过Serv来远程调用一个接口子类的函数方法
功能描述:在MainActivity中通过绑定MyServ服务类,来远程调用MyPlayer(实现了IPlayer接口)的方法过程。需要定义一个IPlayer.aidl文件,ADT工具会自动生成一个IPlayer接口类,然后再由MyPlayer继承IPlayer接口类中的静态内部抽象类,实现接口方法,进而供其它应用程序远程调用。(在本例中为了方便,MainActivity与MyServ类同处一个应用程序中,实现运用时,可以不在同一个应用程序中,只要有权限访问MyServ服务,就能得到IPlayer接口,进而执行该接口实例方法)
程序清单:IPlayer.aidl
ja是什么?
③ Bpxxx的实现Ja,是由Sun
applet)显示了Ja的魅力:跨平台、动态的Web、Internet计算。从此,Ja被广泛接受并推动了Web的迅速发展,常用的浏览器现在均支持Ja
Activity
类(class)负责创建视窗(window),一个活动中的Activity就是在
foreground(前景)模式,背景运行的程序叫做Serv。两者之间通过由ServConnection和AIDL连结,达到复数程序同时运行的效果。如果运行中的
Activity
Activity
取代时,该
Activity
便被停止(stopped),甚至被系统清除(kill)。
View等同于J2ME的Displayable,程序人员可以通过
Vie$(warning Only 64-bit build environments are supported beyond froyo/2.2.)w
类与“XML
layout”档将UI放置在视窗上,Android
1.5的版本可以利用
View
打造出所谓的
Widgets,其实Widget只是View的一种,所以可以使用xml来设计layout,HTC的Android
是各种layout
的基础抽象类(abstract
class),ViewGroup之内还可以有ViewGroup。View的构造函数不需要再Activity中调用,但是Displayable的是必须的,在Activity
中,要通过findViewById()来从XML
中取得View,Android的View类的显示很大程度上是从XML中读取的。View
与(nt)息息相关,两者之间通过Listener
结合在一起,每一个View都可以注册一个nt
listener,例如:当View要处理用户触碰(touch)的时,就要向Android框架注册View.OnClickListener。另外还有Image等同于J2ME的BitMap。
真的是万分后悔当初的选择,当初大学喜欢php是因为当时php很火,而且简单,好学,我的思想就是php要求低(学历英语各方面),而且工资没有ja,c#那些高,我也认为php没有ja那些好,但是ja难,所以我才喜欢php的。你会问为什么感觉php没有ja那些好你还喜欢php呢?因为我的思想就是我选择东西的时候我有时候更害怕选择太好太贵的,因为太贵到时候坏了会很伤心,买来又怕不舍得用,太好的又怕以后没有了不是更伤心,所以我会选择不那么好但是也不那么的,太当然我也不喜欢。当时喜欢php也是如此,觉得并非的那个选择(但是在我的这种思想上其实是当时我觉得最喜欢的选择了),php没有ja那些好,以后淘汰了,钱少也无所谓,丢弃也不会可惜,悲伤,。但是问题来了,本科毕业后php不火了,web前端很流行,我都不知道web前端是做什么的,但是被别人都这么建议我就去学web前端了,学web前端的时候我还是喜欢php,导致毕业我颓废了几年都不想找工作,每天都在想选择php还是选择ja还是是选择web前端还是其他什么的。我想了很多方法想让自己不喜欢php但是好像都不行,但是我现在发现一个问题,当时喜欢php是因为php当时很流行,而且简单,自己接项目好接,钱一般但也还行,而且当时流行创业,php就是适合创业,但是这些都是它的优点啊,我喜欢php还有一个更重要的是因为觉得php不如ja那些,以后如果淘汰不流行可以随时淘汰,但是现在反过来php在我心里面的地位如此之高,我想的都是php那些简单,易学,创业的优点,导致我放不下php,这不是和我当初喜欢php的意愿违背了嘛?现在居然放不下了。所以我又在想,应该综合考虑,综合来看php易学,适合创业,所以很好,ja或者web前端那些就比php难,综合来看没有php那么好,就算学习难易程度,创业也没有php适合,英语学历要求也高点,这么综合来看php要比ja那些更好,所以我更不应该选择php,我如果从综合考虑方向来看,php确实很,如此以来我喜欢了不就是到时候放不下了么?所以我更应该选择ja或者web前端那些综合来说我感觉更些的,因为到时候我更好的能放下啊,而且现在来看我喜欢稳定,还是大众选择多的稳定点吧,比如web前端,后端就是ja,ui设计就不说了设计专业选的。就像当初我也有创业的想法,用php,但是现在来看,压力也大也不适合我啊,自己做的产品,如果不好不赚钱,到时候又不舍得放弃,又在那里耗着也是问题啊,当初如果我综合考虑就好了,当然当时考虑问题没有综合考虑的意识,虽然考虑当时也是多方面的,但还是零零散散的,这么来看我如此放不下php,当初就不应该选择喜欢php,违背了当初我选择它的意愿了,至少当初觉得php没这么好,现在却觉得php非常好导致自己放弃不下,当然当初选择还有一个判断标准是当时思想是觉得工资不多的(虽然php工资还是少点)为什么不选择一个简单易学的,当初的思想都往简单那方向靠拢了,不像现在觉得难点也无所谓,现在已经建立起克服困难的感觉了,如果没有这种感觉容错率就会很低,有点困难就会想着逃避,只要不是非常难都可以在选择范围内,当初选择php也是因为易学这个因素吧,这个也是占很大一部分,当初如果综合考虑,并且把难易考虑进去,难易也算进php和ja,c#那些是否,是否到时候能不能放弃。当然拉,php当初培训便宜也是我喜欢的一个因素,不过现在来看php当时确实是的选择,所以我更不应该选择啊,因为以后淘汰了会不会很悲伤?我应该去选不那么的。是不是很矛盾,不那么的却在我心里是秀的选择,秀的却不是在我心里面是的选择。当然稳定来说还是大众选择的人多比较好,web前端和后端的ja都是选择人很多的,就算是现在也是吧,选择人多虽然竞争大,但是不容易淘汰啊。
Ja是一门面向对象编程语言,可以用来写程序。学会了Ja可以去做节哀吧开发技术。
android怎么实现自动接听和挂断电话功能
Activity是一个应用程序组件,提供一个屏幕,用户可以用来交互为了完成某项任务。添加权限
main.xml
androidrientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> android:layout_width="fill_parent" android:id="@+id/rGrpSelect"> android:layout_width="fill_parent" android:id="@+id/rbtnAutoAccept" android:text="所有来电自动接听"> android:layout_width="fill_parent" android:id="@+id/rbtnAutoReject" android:text="所有来电自动挂断"> android:layout_width="fill_parent" android:id="@+id/tbtnRadioSwitch" android:textOn="Radio已经启动" android:textOff="Radio已经关闭" android:textSize="24dip" android:textStyle="normal"> android:layout_width="fill_parent" andr} catch (Throwable e) {oid:id="@+id/tbtnDataConn" android:textSize="24dip" android:textStyle="normal" android:textOn="允许数据连接" android:textOff="禁止数据连接">
PhoneUtils.ja是手机功能类,从TelephonyMar中实例化ITelephony并返回,源码如下:
package com.testTelephony;
import ja.lang.reflect.Field;
import ja.lang.reflect.Mod;
import com.android.internal.ephony.ITelephony;
import android.ephony.TelephonyMar;
import android.util.Log;
public class PhoneUtils {
/
从TelephonyMar中实例化ITelephony,并返回
/
static public ITelephony getITelephony(TelephonyMar Mgr) throws Exception {
Mod getITelephonyMod = Mgr.getClass().getDeclaredMod("getITelephony");
getITelephonyMod.setAccessible(true);//私有化函数也能使用
return (ITelephony)getITelephonyMod.invoke(Mgr);
}static public void printAllInform(Class clsShow) {
try {
// 取得所有方法
Mod[] hideMod = clsShow.getDeclaredMods();
int i = 0;
for (; i < hideMod.length; i++) {
Log.e("mod name", hideMod.getName());
}// 取得所有常量
Field[] allFields = clsShow.getFields();
for (i = 0; i < allFields.length; i++) {
Log.e("Field name", allFields.getName());
}} catch (SecurityException e) {
// throw new RuntimeException(e.getMessage());
e.printStackTrace();
} catch (IllegalArgumentException e) {
// throw new RuntimeException(e.getMessage());
e.printStackTrace();
// TODO Auto-generated catch block
e.printStackTrace();
}testTelephony.ja是主类,使用PhoneStateListener通话状态,以及实现上述4种电话控制功能,源码如下:
package com.testTelephony;
import android.app.Activity;
import android.os.Bundle;
import android.ephony.PhoneStateListener;
import android.ephony.TelephonyMar;
import android.util.Log;
import android.view.View;
import android.widget.RadioGroup;
import android.widget.ToggleButton;
public class testTelephony extends Activity {
/ Called when the activity is first created. /
RadioGroup rg;//来电作单选框
ToggleButton tbtnRadioSwitch;//Radio开关
ToggleButton tbtnDataConn;//数据连接的开关
TelephonyMar Mgr;
CallStateListener stateListner;
int checkedId=0;
@Override
public void onCreate(Bundle sedInstanceState) {
super.onCreate(sedInstanceState);
setContentView(R.layout.main);
Mgr= (TelephonyMar)getSystemServ(TELEPHONY_SERVICE);
Mgr.listen(new CallStateListener(), CallStateListener.LISTEN_CALL_STATE);
PhoneUtils.printAllInform(TelephonyMar.class);
rg = (RadioGroup)findViewById(R.id.rGrpSelect);
rg.setOnCheckedChangeListener(new CheckEvent());
tbtnRadioSwitch=(ToggleButton)this.findViewById(R.id.tbtnRadioSwitch);
tbtnRadioSwitch.setOnClickListener(new ClickEvent());
try {
tbtnRadioSwitch.setChecked(PhoneUtils.getITelephony(Mgr).isRadioOn());
} catch (Exception e) {
Log.e("error",e.getMessage());
}tbtnDataConn=(ToggleButton)this.findViewById(R.id.tbtnDataConn);
tbtnDataConn.setOnClickListener(new ClickEvent());
try {
tbtnDataConn.setChecked(PhoneUtils.getITelephony(Mgr).isDataConnectivityPossible());
} catch (Exception e) {
Log.e("error",e.getMessage());
/
来电时的作
@author GV
/
public class CheckEvent implements RadioGroup.OnCheckedChangeListener{
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
testTelephony.this.checkedId=checkedId;
/
Radio和数据连接的开关
@author GV
/
public class ClickEvent implements View.OnClickListener{
@Override
public void onClick(View v) {
if (v == tbtnRadioSwitch) {
try {
PhoneUtils.getITelephony(Mgr).setRadio(tbtnRadioSwitch.isChecked());
Log.e("error", e.getMessage());
else if(v==tbtnDataConn){
try {
if(tbtnDataConn.isChecked())
PhoneUtils.getITelephony(Mgr).enableDataConnectivity();
else if(!tbtnDataConn.isChecked())
PhoneUtils.getITelephony(Mgr).disableDataConnectivity();
Log.e("error", e.getMessage());
/
监视电话状态
@author GV
/
public class CallStateListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
if(state==TelephonyMar.CALL_STATE_IDLE)//挂断
{Log.e("IDLE",incomingNumber);
}else if(state==TelephonyMar.CALL_STATE_OFFHOOK)//接听
{Log.e("OFFHOOK",incomingNumber);
}else if(state==TelephonyMar.CALL_STATE_RINGING)//来电
{if(testTelephony.this.checkedId==R.id.rbtnAutoAccept)
{try {
//需要
PhoneUtils.getITelephony(Mgr).silenceRinger();//静铃
PhoneUtils.getITelephony(Mgr).answerRingingCall();//自动接听
Log.e("error",e.getMessage());
else if(testTelephony.this.checkedId==R.id.rbtnAutoReject)
{try {
PhoneUtils.getITelephony(Mgr).endCall();//挂断
PhoneUtils.getITelephony(Mgr).cancelMissedCallsNotification();//取消未接显示
Log.e("error",e.getMessage());
}super.onCallStateChanged(state, incomingNumber);
}
新人求教,编译一个最简单的Android程序,提示下面的错误咋解决
applet。 Android以Ja为编程语言,使接口到功能,都有层出不穷的变化,其中Activity等同于J2ME的MIDlet,一个注意以下事项:
1、32位系统下的编译
如果需要在32位系统中编译android系统,在编译前需要对部分makefile进行修改
首先修改build/core/main.mk,修改的内容如下所示:
-ifneq (64,$(findstring 64,$(build_arch)))
+ifneq
(i686,$(findstring i686,$(build_arch)))
$(warning
) $(warning You are attempting to build on a 32-bit .)
其次修改如下四个文件:
external/clearsilver/cgi/Android.mk
external/clearsilver/ja-jni/Android.mk
external/clearsilver/util/Android.mk
external/clearsilver/cs/Android.mk # This forces a 64-bit build for Ja6
-LOCAL_CFLAGS += -m64
-LOCAL_LDFLAGS += -m64
+LOCAL_LDFLAGS += -m32即将LOCAL_CFLAGS和LOCAL_LDFLAGS由-m64改为-m32,从而指定使用32位系统进行编译如果使用 64bit 的作系统编译,这些就都不用修改,但记得需要安装:For 64-bit servers the following extra packages may be needed:
"sudo apt-get install libc6-dev-i386" (libc6-dev-amd64 if AMD CPU)
"sudo apt-get install g++-multilib lib32ncurses5-dev lib32z1-dev"
还有 jdk64bit 的版本编译2 、build/core/base_rules.mk:128: frameworks/opt/emoji/jni:
.... libgl2jni already defined by framwworks/base/opengl/tests/gl2_jni/jni 停止
从编译规则上看:
# Make sure that this IS_HOST/CLASS/MODULE combination is unique.
module_id := MODULE.$(if
$(LOCAL_IS_HOST_MODULE),HOST,TARGET).$(LOCAL_MODULE_CLASS).$(LOCAL_MODULE)
ifdef $(module_id)
$(error $(LOCAL_PATH): $(module_id) already defined by $($(module_id)))
endif
在framwworks/base/opengl/tests/gl2_jni/下面定义的android.mk定义了:
LOCAL_MODULE := libgl2jni
include $(BUILD_SHARED_LIBRARY)
导致生成的动态库重复,这是不对的,修改tests这个目录不参与编译即可,最直接的办法删除掉framwworks/base/opengl/tests/gl2_jni这个文件夹
3、AIDL 编译报couldn't find import for class原因
“AIDL服务只支持有限的数据类型,因此,如果用AIDL服 务传递一些复杂的数据就需要做更一步处理。AIDL服务支持的数据类型如下:
Ja的简单类 型(int、char、boolean等)。不需要导入(import)。String和 CharSequence。不需要导入(import)。
List和 Map。但要注意,List和Map对象的元素类型必须是AIDL服务支持的数据类型。不需要导入(import)。AIDL自动生成 的接口。需要导入(import)。
实现 android.os.Parcelable接口的类。需要导入(import)。
其中后两种数据类 型需要使用import进行导入,传递不需要 import的数据类型的值的方式相同。传递一个需要import的数据类型的值(例如,实现android.os.Parcelable 接口的类)的步 骤略显复杂。除了要建立一个实现android.os.Parcelable接口的类外,还需要为这个类单独建立一个aidl文件,并使用parcelable关键字进行定义。”
没有加LOCAL_AIDL_INCLUDES += xxx ,所以找不到我的parcelable aidl文件。
修改android源码根目录下的build/core/pathmap.mk把你的目录加进去,此时再make update-api
4、老是提示 @Override错误 方法未覆盖其父类的方法
使 用JDK1.6编译没有问题,使用JDK1.5编译,会报@Override方法未覆盖其父类的方法。实际上这个方法是类实现的接口中方法,
但是,这个语 法的jdk1.6的下面是可以通过的,也就是说jdk1.6认为类覆盖父类方法与实现接口方法都叫override,而jdk1.5不
是这样认为的,不知 道这是当初jdk1.5的bug,还是当初就是认为覆盖父类方法与实现接口方法是不一样的,不得而知。但是从
OO角度来看,覆盖父类方法与实现接口方法都 可以认为override,因为他们目的都是一样的,都是为了重用,都是多态的一种
表现方式。
更改jdk版本为1.6即可
5、编译alsa-lib库错误
android系统开发移植alsa-lib库的过程中编译的时候出现了如下的错误
/tmp/cckyaR40.s: Assembler messages:
/tmp/cckyaR40.s:2763: Error: selected processor does not support `mrs ip,cpsr'
/tmp/cckyaR40.s:2764: Error: unshifted register required -- `orr r2,ip,#128'
/tmp/cckyaR40.s:2765: Error: selected processor does not support `msr cpsr_c,r2
字面的意思报的是汇编错误,选择的处理器不支持mrs和msr指令。
原来的ARM指令有32位和16位两种指令模式,16位为thumb指令集,thumb指令集编译出的代码占用空间小,
而且效率也高,所以android的arm编译器默认用的是thumb模式编译,问题在于alsa的代码中有部分的内容
用到了32位的指令,所以才会报如下的错误,修改的方法也很简单,在Android.mk中加入如下内容即可:
LOCAL_ARM_MODE := arm
android的编译系统中LOCAL_ARM_MODE变量的取值为arm或者thumb,代表32位和16位两种arm指令集,默认为thumb
prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/bin/ld: failed to set dynamic section sizes: Bad value
collect2: ld returned 1 exit status
make: [out/target/product/merlin/obj/SHARED_LIBRARIES/libasound_intermediates/LINKED/libasound.so] 错误 1
解决此问题将alsa-lib/include/config.h文件中的如下宏定义去掉即可:
#define VERSIONED_SYMBOLS
开发过程中碰到过很多错误,后续再一一总结记录下来,有些忘记了。。
在android.mk中编译:
include $(CLEAR_VARS)
$(call add-prebuilt-files, STATIC_LIBRARIES, libyfcdca.a)
出现提示需要定义:LOCAL_MODULE_TAGS := optional 一般修改方法是:
buildcoredefinitions.mk 中的宏定义变量:
define include-prebuilt
include $$(CLEAR_VARS)
LOCAL_SRC_FILES := $(1)
LOCAL_BUILT_MODULE_STEM := $(1)
LOCAL_MODULE_SUFFIX := $$(suffix $(1))
LOCAL_MODULE := $$(basename $(1))
incluMicros公司于1995年5月推出的Ja程序设计语言和Ja平台的总称。用Ja实现的HotJa浏览器(支持Jade $$(BUILD_PREBUILT)
endef
在这里增加一个LOCAL_MODULE_TAGS := optional
但是这需要修改android源码,如果不是自已的android系统,这么做就麻烦了,所以必须想其它办法解决:
#include $(CLEAR_VARS)
#$(call add-prebuilt-files, STATIC_LIBRARIES, libyfcdca.a)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := libyfcdca.a
LOCAL_MODULE_SUFFIX := lib
LOCAL_MODULE := yfcdca
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
LOCAL_MODULE_TAGS := optional
include $(BUILD_PREBUILT)
如此即可了。
如何在Android中添加系统服务
mStr = in.readString();在android中添加系统服务,下面以SuceComer这个serv为例,
① 首先提供接口文件ISuceComer.h
//frameworksnativeincludeguiISuceComer.h
//首先是接口,c++实现是虚函数
class ISuceComer: public IIntece {
public:
DECLARE_META_INTERFACE(SuceComer);
// flags for setTransactionState()
enum {
eSynchronous = 0x01,
eAnimation = 0x02,
};
enum {
eDisplayIdMain = 0,
};
/ create connection with suce flinger, requires
ACCESS_SURFACE_FLINGER permission
/
virtual sp
}② 建立BnSuceComer
建立BnSuceComer,需要重写BBinder的onTransact函数。
class BnSuceComer: public BnIntece
public:
enum {
// Note: BOOT_FINISHED must remain this value, it is called from
// Ja by ActivityMarServ.
BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
CREATE_CONNECTION,
CREATE_GRAPHIC_BUFFER_ALLOC,
CREATE_DISPLAY__CONNECTION,
CREATE_DISPLAY,
DESTROY_DISPLAY,
GET_BUILT_IN_DISPLAY,
SET_TRANSACTION_STATE,
AUTHENTICATE_SURFACE,
BLANK,
UNBLANK,
GET_DISPLAY_INFO,
CONNECT_DISPLAY,
CAPTURE_SCREEN,
};
virtual status_t onTransact(uint32_t code, const Parcel& data,
Parcel reply, uint32_t flags = 0);
};
frameworksnativelibsguiISuceComer.cpp中,
//Bp实现,端
class BpSuceComer : public BpIntece
{public:
BpSuceComer(const sp
: BpIntece
{}
//接口
virtual sp
{uint32_t n;
Parcel data, reply;
data.writeInteceToken(ISuceComer::getInteceDescriptor());
remote()->transact(BnSuceComer::CREATE_CONNECTION, data, &reply);
return intece_cast
④ Bnxxx的实现
//Bn端,即server端
status_t BnSuceComer::onTransact(
uint32_t code, const Parcel& data, Parcel reply, uint32_t flags)
package android.app;{switch(code) {
case CREATE_CONNECTION: {
CHECK_INTERFACE(ISuceComer, data, reply);
//createConnection就是server端的实现函数
sp
reply->writeStrongBinder(b);
return NO_ERROR;
}default: {
return BBinder::onTransact(code, data, reply, flags);
// should be unreachable
return NO_ERROR;
}⑤ 注册serv
通过上面几步已经完成了serv的建立,我们需要将serv注册到serv mar中。
class SuceFlinger : public BnSuceComer,
//在frameworksnativeservssuceflingermain_suceflinger.cpp中,
// publish suce flinger
sp
->addServ(String16(SuceFlinger::getServName()), flinger, false);
⑥ 使用serv
//首先获取端BpSuceComer
sp
//直接调用BpSuceComer的接口
sp
其中getComerServ()的实现为,
/static/ sp
ComerServ& instance = ComerServ::getInstance();
Mutex::Autolock _l(instance.mLock);
if (instance.mComerServ == NULL) {
ComerServ::getInstance().connectLocked();
assert(instance.mComerServ != NULL);
ALOGD("ComerServ reconnected");
}return instance.mComerServ;
}void ComerServ::connectLocked() {
const String16 name("SuceFlinger");
//获取serv,返回的mComerServ是BpSuceComer,有了Bp就能直接调用接口了
while (getServ(name, &mComerServ) != NO_ERROR) {
usleep(000);
}assert(mComerServ != NULL);
// Create the death listener.
class DeathObserver : public IBinder::DeathRecipient {
ComerServ& mComerServ;
virtual void binderDied(const wp
ALOGW("ComerServ remote (suceflinger) died [%p]",
who.unsafe_get());
mComerServDied();
}public:
DeathObserver(ComerServ& mgr) : mComerServ(mgr) { }
};
mDeathObserver = new DeathObserver(const_cast
mComerServ->asBinder()->linkToDeath(mDeathObserver);
}ja添加serv
Android为了方便开发人员,提供了AIDL工具,简化了编写serv的难度。下面以添加TestServ这个服务为例,
① 编写AIDL文件
intece ITestServ {
boolean enableWifi(boolean enabled);
}TestServ的AIDL文件提供了一个接口,enableWifi()。
② 创建TestServ服务
TestServ 服务需要继承ITestServ.Stub类,这个类就是通过AIDL工具对①中的AIDL文件处理后产生的,
class TestServ extends ITestServ.Stub {
//实现接口
{......
③ Context.ja中添加serv名字字符串
// Context.ja中添加serv名字字符串
public static final String TEST_SERVICE = "my_test";
④ 向ServMar中注册serv
ja中大部分的系统serv都是在System中去向serv mar注册的,
//ServMar注册serv
// 在System.ja中,模仿其他向ServMar添加serv的方法
try {
TestServ myServ = new TestServ(context);
ServMar.addServ(Context.TEST_SERVICE, myServ);
reportWtf("register my test serv fail", e);
}⑤创建服务对应的Mar
对于每一个serv而言,通常会有一个相关的Mar。 Mars提供API给app使用,成为SDK的一部分,是apps和remote serv的中间桥梁。Mar中的接口和Serv中的接口必须一一对应。
private final ITestServ mServ;
private final Context mContext;
//构造函数中传入的serv,其实就是BpTestServ
TestServMar(Context context,ITestServ serv) {
mServ = serv;
}public boolean enableWifi(boolean enabled) {
try {
return mServ.enableWifi(enabled);
} catch (RemoteException ex) {
}return false;
到目前为止,我们只是完成了Serv的注册,但是还没有使用,该如何使用?
⑥ contextImpl中注册Mar
一旦我们实现了serv和对应的Mar,需要有一种方法在app中调用他们。前面说过,Mar会成为SDK的一部分,供我们调用,那么Mar和Serv是如何联系起来的?首先需要将我们的serv和mangager注册到execution context,即contextImpl中,
registerServ(TEST_SERVICE, new ServFetcher() {
public Object createServ(ContextImpl ctx) {
IBinder b = ServMar.getServ(TEST_SERVICE);
//asIntece(BpBinder)后就是BpTestServ
ITestServ serv = ITestServ.Stub.asIntece(b);
//创建TestServMar,第二个参数为BpBpTestServ
return new TestServMar(ctx.getOuterContext(), serv);
}});
registerServ的第二个参数是一个ServFetcher对象,这里直接在调用时,新建了一个ServFetcher类,重写了createServ方法。
ContextImpl.ja中的registerServ()方法,其核心就是把servname和ServFetcher对象放到一个Hash的键值对中。
private static void registerServ(String servName, ServFetcher fetcher) {
if (!(fetcher instanceof StaticServFetcher)) {
fetcher.mContextCacheIndex = sNextPerContextServCacheIndex++;
}SYSTEM_SERVICE_MAP.put(servName, fetcher);
}⑦ app如何使用serv
那么app是如何调用的呢?
import android.app.TestServMar;
import android.content.Context;
TestServMar mTestServMar;
mTestServMar=(TestServMar)context.getSystemServ(Context.TEST_SERVICE);
然后直接调用TestServMar中的方法即可,其中的奥秘需要分析下getSystemServ函数。
ContextImpl.ja中,
@Override
public Object getSystemServ(String name) {
ServFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
//从ServFetcher 中获取serv
return fetcher == null ? null : fetcher.getServ(this);
}getServ()函数的核心就是上面重写的createServ()函数,返回的就是TestServMar对象,所以通过context.getSystemServ返回的是Mar对象。
public Object getServ(ContextImpl ctx) {
ArrayList
Object serv;
synchronized (cache) {
if (cache.size() == 0) {
// Initialize the cache vector on first access.
// At this point sNextPerContextServCacheIndex
// is the number of potential servs that are
// cached per-Context.
for (int i = 0; i < sNextPerContextServCacheIndex; i++) {
cache.add(null);
}} else {
serv = cache.get(mContextCacheIndex);
if (serv != null) {
return serv;
//调用重载的createServ函数,返回的就是TestServMar对象
serv = createServ(ctx);
cache.set(mContextCacheIndex, serv);
return serv;
Android 进程间通信的几种实现方式
Hero手机即含有大量的widget。至于ViewGroup①Activity (借助Intent调用其他APP的Activity实现跨进程通信)
+LOCAL_CFLAGS += -m32Android四大组件之一
Activity中所有作都与用户密切相关,是一个负责与用户交互的组件,可以通过setContentView(View)来显示指定控件。
在一个android应用中,一个Activity通常就是一个单独的屏幕,它上面可以显示一些控件也可以并处理用户的做出响应。Activity之间通过Intent进行通信。
②广播接收者(BroadcastReceiver)
Android四大组件之一,有广播接收者,与之对应要有发送者。
广播被分为两种不同的类型:“普通广播(Normal broadcasts)”和“有序广播(Ordered broadcasts)”。
普通广播是完全异步的,可以在同一时刻(逻辑上)被所有接收者接收到,消息传递的效率比较高,
但缺点是:接收者不能将处理结果传递给下一个接收者,并且无法终止广播Intent的传播。
然而有序广播是按照接收者声明的优先级别,被接收者依次接收广播。如:A的级别高于B,B的级别高于C,那么,广播先传给A,再传给B,传给C 。
③内容提供者(ContentProvider)
Android四大组件之一,有提供者,与之对应也要有调用者。
④AIDL(Android Intece definition language,Android接口定义语言)
与之前三个相比,AIDL可能稍显复杂。
Serv,Android四大组件之一,借助AIDL也可以实现跨进程访问服务
// IRemoteServ.aidl
package com.example.android;
// Declare any non-default types here with import statements
/ Example serv intece /
intece IRemoteServ {
/ Request the process ID of this serv, to do evil things with it. /
int getPid();
/ 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);
}这段为文档,可参考定义
在com.example.android包下
进程间通信就是在不同进程之间传播或交换信息,那么不同进程之间存在着什么双方都可以访问的介质呢?进程的用户空间是互相的,一般而言是不能互相访问的,的例外是共享内存区。但是,系统空间却是“公共场所”,所以内核显然可以提供这样的条件。除此以外,那就是双方都可以访问的外设了。在这个意义上,两个进程当然也可以通过磁盘上的普通文件交换信息,或者通过“注册表”或其它数据库中的某些表项和记录交换信息。广义上这也是进程间通信的手段,但是一般都不把这算作“进程间通信”。因为那些通信手段的效率太低了,而人们对进程间通信的要求是要有一定的实时性。
进程间通信主要包括管道, 系统IPC(包括消息队列,信号量,共享存储), SOCKET.
管道包括三种:1)普通管道PIPE, 通常有种限制,一是半双工,只能单向传输;二是只能在父子进程间使用. 2)流管道s_pipe: 去除了种限制,可以双向传输. 3)命名管道:name_pipe, 去除了第二种限制,可以在许多并不相关的进程之间进行通讯.
系统IPC的三种方式类同,都是使用了内核里的标识符来识别.
# 管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
# 有名管道 (named pipe) : 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
# 信号量( semophore ) : 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
Android Parcelable和Serializable的区别
Parcelable和Serializable的作用、效率、区别及选择:
1、作用
Serializable的作用是为了保存对象的属性到本地文件、数据库、网络流、rmi以方便数据传输,当然这种传输可以是程序内的也可以是两个程序间的。而Android的Parcelable的设计初衷是因为Serializable效率过慢,为了在程序内不同组件间以及不同Android程序间(AIDL)高效的传输数据而设计,这些数据仅在内存中存在,Parcelable是通过IBinder通信的消息的载体。
从上面的设计上我们就可以看出优劣了。
2、效率及选择
Parcelable的性能比Serializable好,在内存开销方面较小,所以在内存间数据传输时使用Parcelable,如activity间传输数据,而Serializable可将数据持久化方便保存,所以在需要保存或网络传输数据时选择Serializable,因为android不同版本Parcelable可能不同,所以不使用Parcelable进行数据持久化
3、编程实现
对于Serializable,类只需要实现Serializable接口,并提供一个序列化版本id(serialVersionUID)即可。而Parcelable则需要实现writeToParcel、describeContents函数以及静态的CREATOR变量,实际上就是将如何打包和解包的工作自己来定义,而序列化的这些作完全由底层实现。
ParLOCAL_MODULE_CLASS := $(2)celable的一个实现例子如下
[ja] view plaincpublic boolean enableWifi(boolean enabled)opy
public class MyParcelable implements Parcelable {
private int mData;
private String mStr;
public int describeContents() {
return 0;
}// 写数据进行保存
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
out.writeString(mStr);
}// 用来创建自定义的Parcelable的对象
public static final Parcelable.Creator
= new Parcelable.Creator
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}};
// 读数据进行恢复
private MyParcelable(Parcel in) {
mData = in.readInt();
从上面我们可以看出Parcel的写入和读出顺序是一致的。如果元素是list读出时需要先new一个ArrayList传入,否则会报空指针异常。如下:
in.readStringList(list);
PS: 在自己使用时,read数据时误将前面int数据当作long读出,结果后面的顺序错乱,报如下异常,当类字段较多时务必保持写入和读取的类型及顺序一致。
11-21 20:14:10.317: E/AndroidRuntime(21114): Caused by: ja.lang.RuntimeException: Parcel android.os.Parcel@4126ed60: Unmarshalling unknown type code 3014773 at offset 164
4、高级功能上
Serializable序列化不保存静态变量,可以使用Transient关键字对部分字段不进行序列化,也可以覆盖writeObject、readObject方法以实现序列化过程自定义
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系 836084111@qq.com 删除。