droid

阅读 / 问答 / 标签

win7安装android sdk老出 Fetching https://dl-ssl.google.com/android/repository/addons_list-1.xml Fa

可以在爱预合里认识朋友开心交流,找到暖心人一起快乐,给你开心感觉。

Android studio 启动一直提示Fetching android sdk component information,求大神们给个解救方法,在线等

网上有人给出了方案:1)进入刚安装的Android Studio目录下的bin目录。找到idea.properties文件,用文本编辑器打开。2)在idea.properties文件末尾添加一行: disable.android.first.run=true ,然后保存文件。3)关闭Android Studio后重新启动,便可进入界面。可以解决。

android studio canary,dev,beta,stable.开发者选哪个

目前谷歌有dev(开发版)、bata(测试版)、Canary(金丝雀版)和stable(稳定版)金丝雀(Canary)版Chrome是Google推出的一个特别版Chrome.可以同时安装/运行两个Chrome版本,比如,安装Chrome 稳定版/Beta测试版/开发者版本,同时安装使用Chrome金丝雀版本(目前仅支持Windows XP、Vista、Windows 7平台).

android canvas怎么创建

工具/原料电脑(windows)eclipse+android编程环境方法/步骤首先新建一个android项目名字为CanvasShow,其余参数可以自己配置,点击完成,形成项目信息配置main.xml,在这里main.xml 基本不用修改,只需增加<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"android:id="@+id/root"></LinearLayout>CanvasShowInfo中实现方法:@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);init();}private void init() { LinearLayout layout=(LinearLayout) findViewById(R.id.root); final CanvasDraw view=new CanvasDraw(this); view.setMinimumHeight(500); view.setMinimumWidth(300); //通知view组件重绘 这个很重要!view.invalidate(); layout.addView(view); } 那么CanvasDraw.java中实现了什么呢?声明CanvasDraw.java 继承View,重写其中的onDraw方法。比如画圆:// 创建画笔 Paint p = new Paint(); p.setColor(Color.RED);// 设置红色 canvas.drawText("画圆:", 10, 20, p);// 画文本 canvas.drawCircle(40, 40, 15, p);// 分别是 圆心的x,y坐标,15为半径 p.setAntiAlias(true);// 设置画笔的锯齿效果。 true是去除,大家一看效果就明白了 canvas.drawCircle(100, 120, 50, p);// 分别是 圆心的x,y坐标,50为半径从图中可以看见,去除锯齿的图形更加圆滑。下面是相对应的效果图canvas.drawText("画矩形:", 10, 90, p); p.setColor(Color.BLUE);// 设置灰色 p.setStyle(Paint.Style.FILL);//设置填满 canvas.drawRect(60, 60, 80, 80, p);// 正方形 canvas.drawRect(70, 90, 300, 100, p);// 长方形 // drawRect函数前两个参数是一个顶点的坐标,后两个参数是对顶点的坐标,相对应的效果图canvas.drawText("画扇形:", 120, 120, p); // 设置渐变色 这个扇形的颜色是改变的 / Shader mShader = new LinearGradient(0, 0, 100, 100, new int[] { Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW, Color.LTGRAY }, null, Shader.TileMode.REPEAT); // 一个材质,打造出一个线性梯度沿著一条线。 p.setShader(mShader); p.setColor(Color.BLUE); RectF oval2 = new RectF(60, 100, 200, 240);// 设置个新的长方形,扫描测量 canvas.drawArc(oval2, 200, 130, true, p); // 画弧,第一个参数是RectF:该类是第二个参数是角度的开始,第三个参数是多少度,第四个参数是真的时候画扇形,是假的时候画弧线 其中:public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)oval :指定圆弧的外轮廓矩形区域。startAngle: 圆弧起始角度,单位为度。sweepAngle: 圆弧扫过的角度,顺时针方向,单位为度。useCenter: 如果为True时,在绘制圆弧时将圆心包括在内,通常用来绘制扇形。paint: 绘制圆弧的画板属性,如颜色,是否填充等。

android绘图之Canvas基础(2)

Canvas画布,用于绘制出各种形状配合画布的变幻操作可以绘制出很多复杂图形,基本的绘制图形分类。 提供的绘制函数: 上面四个函数都可以绘制canvas的背景,注意到PorterDuff.Mode变量,它只对两个canvas绘制bitmap起作用,所以此处暂时不讨论mode参数(没有设置mode默认使用srcover porterduff mode)。 Rect 和RectF都是提供一个矩形局域。 (1)精度不一样,Rect是使用int类型作为数值,RectF是使用float类型作为数值。 (2)两个类型提供的方法也不是完全一致。 ** rect:RectF对象,一个矩形区域。 rx:x方向上的圆角半径。 ry:y方向上的圆角半径。 paint:绘制时所使用的画笔。** ** cx 圆心x cy 圆心y radius半径** 需要一个Path,代表路径后面会讲解。 绘制线的集合,参数中pts是点的集合,两个值代表一个点,四个值代表一条线,互相之间不连接。 offset跳过的点,count跳过之后要绘制的点的总数,可以用于集合中部分点的绘制。 跳过部分节点: 没有跳过点 RectF oval:生成弧的矩形,中心为弧的圆心 float startAngle:弧开始的角度,以X轴正方向为0度,顺时针 float sweepAngle:弧持续的角度 boolean useCenter:是否有弧的两边,True,还两边,False,只有一条弧 在矩形框内画一个椭圆,如果是个正方形会画出一个圆。 canvas.drawPoint(); canvas.drawPoints(); ** 只需要提供两个点一个坐标就可以绘制点。 canvas.drawPoint(20,20,mPaint); float[] points = {30,40,40,50,60,60}; canvas.drawPoints(points,mPaint);** 这几种方法类似: canvas.drawText("好好学习,天天向上",100,100,mPaint); drawTextOnPath 沿着一条 Path 来绘制文字 text 为所需要绘制的文字 path 为文字的路径 hOffset 文字相对于路径的水平偏移量,用于调整文字的位置 vOffset 文字相对于路径竖直偏移量,用于调整文字的位置 值得注意的是,在绘制 Path 的时候,应该在拐弯处使用圆角,这样文字显示时更舒服 大致讲解,后面会重点讲解。 Rect src Rect dst 其中src和dst这两个矩形区域是用来做什么的? Rect src:指定绘制图片的区域 Rect dst或RectF dst:指定图片在屏幕上的绘制(显示)区域 首先指定图片区域,然后指定绘制图片的区域。 android绘图之Paint(1) android绘图之Canvas基础(2) Android绘图之Path(3) Android绘图之drawText绘制文本相关(4) Android绘图之Canvas概念理解(5) Android绘图之Canvas变换(6) Android绘图之Canvas状态保存和恢复(7) Android绘图之PathEffect (8) Android绘图之LinearGradient线性渐变(9) Android绘图之SweepGradient(10) Android绘图之RadialGradient 放射渐变(11) Android绘制之BitmapShader(12) Android绘图之ComposeShader,PorterDuff.mode及Xfermode(13) Android绘图之drawText,getTextBounds,measureText,FontMetrics,基线(14) Android绘图之贝塞尔曲线简介(15) Android绘图之PathMeasure(16) Android 动态修改渐变 GradientDrawable

android开发中Final、finally、finanlize()的区别是什么?

【答案】:final用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。finally是异常处理语句结构的一部分,表示总是执行。finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。

android apn bearer 对应0么

如何在android中使用摄像头获取照片

/** * 从相册中获取,返回结果会在onActivityResult()中 */ private void selectPicFromAlbum() { Intent intent = new Intent(); intent.setAction(Intent.ACTION_GET_CONTENT); intent.setType("image/*"); startActivityForResult(intent, RESULT_FROM_ALBUM); } /** * 从摄像头中获取,返回结果会在onActivityResult()中 */ private void selectPicFromCamera() { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTUR

android 作为服务器端 可以用mina么

Android studio怎么使用groovy console命令

Android studio 使用groovy console命令的具体方法如下: 进行打开Android studio的软件,进入到界面中,进行点击菜单中的“tools”的选项。 就会弹出了一个下拉的菜单的选项,进行选择下拉的菜单中的“Groovy console”的选项。 在代码的窗口当中就...

android studio 怎么配置 groovy

主要讲下Android Studio如何开发Groovy,搭环境这东西,最恶心。我查了N多的外文。。。。1.AS(Android Studio)本身是支持Groovy的,Gradle用的语法就是Groovy。也可以在AS中直接创建.groovy后缀的文件。2.Project、Module的build.gradle可以将目录的展现形式改为Android来识别:(后续添加:在D:Program FilesAndroidAndroid Studiogradlegradle-2.4samplesz中有详细的使用Gradle配置的例子scala、maven、groovy、eclipse等等,看来学习方法很重要啊!)

android 布局xml中 android:fitsSystemWindows="true" 这一句是什么意思?有什么作用?

简单的讲:设置应用布局时是否考虑系统窗口布局;如果为true,将调整系统窗口布局以适应你自定义的布局。比如系统有状态栏,应用也有状态栏时。看你这个布局代码,恰恰是在定义标题栏样式,所以用到这行代码了。

Carson带你学Android:手把手教你写一个完整的自定义View

自定义View一共分为两大类,具体如下图: 对于自定义View的类型介绍及使用场景如下图: 在使用自定义View时有很多注意点(坑),希望大家要非常留意: View的内部本身提供了post系列的方法,完全可以替代Handler的作用,使用起来更加方便、直接。 主要针对View中含有线程或动画的情况: 当View退出或不可见时,记得及时停止该View包含的线程和动画,否则会造成内存泄露问题 。 当View带有滑动嵌套情况时,必须要处理好滑动冲突,否则会严重影响View的显示效果。 接下来,我将用自定义View中最常用的 继承View 来说明自定义View的具体应用和需要注意的点 在下面的例子中,我将讲解: 下面我将逐个步骤进行说明: 步骤1:创建自定义View类(继承View类) 特别注意: 步骤2:在布局文件中添加自定义View类的组件及显示 至此,一个基本的自定义View已经实现了,运行效果如下图。 接下来继续看自定义View关于属性自定义的问题: 先来看wrap_content & match_parent属性的区别 如果不手动设置支持 wrap_content 属性,那么 wrap_content 属性是不会生效(显示效果同 match_parent ) padding 属性:用于设置控件内容相对控件边缘的边距; 如果不手动设置支持padding属性,那么padding属性在自定义View中是不会生效的。 绘制时考虑传入的padding属性值(四个方向)。 除了常见的以android:开头的系统属性(如下所示),很多场景下自定义View还需要系统所没有的属性,即自定义属性。 实现自定义属性的步骤如下: 下面我将对每个步骤进行具体介绍 对于自定义属性类型 & 格式如下: 至此,一个较为规范的自定义View已经完成了。 Carson_Ho的github: 自定义View的具体应用 不定期分享关于 安卓开发 的干货,追求 短、平、快 ,但 却不缺深度 。

android的gsensor的hal层enable值怎样到驱动层

Android上层应用apk到G-sensor driver的大致流程: Android HAL层,即硬件抽象层,是Google响应厂家“希望不公开源码”的要求推出的新概念 1,源代码和目标位置 源代码: /hardware/libhardware目录,该目录的目录结构如下: /hardware/libhardware/hardware.c编译成libhardware.so,目标位置为/system/lib目录 /hardware/libhardware/include/hardware目录下包含如下头文件: hardware.h 通用硬件模块头文件 copybit.h copybit模块头文件 gralloc.h gralloc模块头文件 lights.h 背光模块头文件 overlay.h overlay模块头文件 qemud.h qemud模块头文件 sensors.h 传感器模块头文件 /hardware/libhardware/modules目录下定义了很多硬件模块 这些硬件模块都编译成xxx.xxx.so,目标位置为/system/lib/hw目录 2,Android对于Sensor的API定义在 hardware/libhardware/include/hardware/sensor.h中,要求在sensor.so提供以下8个API函数 [控制方面] int (*open_data_source)(struct sensors_control_device_t *dev); int (*activate)(struct sensors_control_device_t *dev, int handle, int enabled); int (*set_delay)(struct sensors_control_device_t *dev, int32_t ms); int (*wake)(struct sensors_control_device_t *dev); [数据方面] int (*data_open)(struct sensors_data_device_t *dev, int fd); int (*data_close)(struct sensors_data_device_t *dev); int (*poll)(struct sensors_data_device_t *dev, sensors_data_t* data); [模块方面] int (*get_sensors_list)(struct sensors_module_t* module, struct sensor_t const** list); 在Java层Sensor的状态控制由SensorService来负责,它的java代码和JNI代码分别位于: frameworks/base/services/java/com/Android/server/SensorService.java frameworks/base/services/jni/com_Android_server_SensorService.cpp 在Java层Sensor的数据控制由SensorManager来负责,它的java代码和JNI代码分别位于: frameworks/base/core/java/Android/hardware/SensorManager.java frameworks/base/core/jni/Android_hardware_SensorManager.cpp Android framework中与sensor通信的是sensorService.java和sensorManager.java。 sensorService.java的具体通信是通过JNI调用sensorService.cpp中的方法实现的。 sensorManager.java的具体通信是通过JNI调用sensorManager.cpp中的方法实现的。 sensorService.cpp和sensorManger.cpp通过hardware.c与sensor.so通信。其中sensorService.cpp实现对sensor的状态控制,sensorManger.cpp实现对sensor的数据控制。 sensor.so通过ioctl控制sensor driver的状态,通过打开sensor driver对应的设备文件读取G-sensor采集的数据。 Android SDK提供了4个类来于sensor通信,分别为 sensor,sensorEvent,sensorEventListener,sensorManager。其中 sensorEventListener用来在sensorManager中注册需要监听的sensor类型。 sensorManager.java提供registrater(),unregistrater()接口供sensorEventListener使用。 sensorManager.java不断轮询从sensor.so中取数据。取到数据后送给负责监听此类型sensor的 sensorEventListener.java。sensorEventListener.java通过在sensorManager.java中注册可以监听特定类型的sensor传来的数据。 系统启动时执行systemProcess,会启动sensorService.java,在sensorService.java的构造函数中调用JNI方法_sensor_control_init()。 sensorService.cpp中相应的方法Android_int()会被执行。该函数会调用hardware.c中的方法hw_get_module()此函数又通过调用load()函数在system/lib/hw下查找sensor.so 查找时会根据harware.c中定义好的sensor.*.so的扩展名的顺序查找,找到第一个匹配的时候即停止,并将该sensor.so中定义好的一个全局变量HAL_MODULE_INFO_SYM带回。该变量包含的一个 重要信息是它的一个成员结构变量中包含的一个函数指针open,该指针所指函数会对一个device结构变量赋值,从而带出sensorService.cpp和sensorManager.cpp与sensor通信所需要的全部信息。 device结构变量有两种变体分别供sensorService.cpp和sensorManaer.cpp使用。其中主要是一些函数指针指向与sensor通信的函数。 sensorService.cpp和sensorManager.cpp在得到HAL_MODULE_INFO_SYM结构后都会调用 sensors.h的inline函数open()通过HAL_MODULE_INFO_SYM的open函数指针将所需的device信息取回。 系统在启动activityManager.java时,它会启动sensorManager.java,它也会调用hardware.c中的方法hw_get_module()带回HAL_MODULE_INFO_SYM。

这是什么东西,点了三下Android版本号就出来了

设置安卓系统点击几下就出来了

Android中的Activity详解--启动模式与任务栈

目录 activity的简单介绍就不写了,作为最常用的四大组件之一,肯定都很熟悉其基本用法了。 首先,是都很熟悉的一张图,即官方介绍的Activity生命周期图. 情景:打开某个应用的的FirstActivity调用方法如下: 由于之前已经很熟悉了,这里就简单贴一些图。 按下返回键: 重新打开并按下home键: 再重新打开: 在其中打开一个DialogActivity(SecondActivity) 按下返回: 修改SecondAcitvity为普通Activity,依旧是上述操作: 这里强调一下 onSaveInstanceState(Bundle outState) 方法的调用时机: 当Activity有可能被系统杀掉时调用,注意,一定是被系统杀掉,自己调用finish是不行的。 测试如下:FirstActivity启动SecondActivity: 一个App会包含很多个Activity,多个Activity之间通过intent进行跳转,那么原始的Activity就是使用栈这个数据结构来保存的。 Task A task is a collection of activities that users interact with when performing a certain job. The activities are arranged in a stack (the back stack ), in the order in which each activity is opened. 即若干个Activity的集合的栈表示一个Task。 当App启动时如果不存在当前App的任务栈就会自动创建一个,默认情况下一个App中的所有Activity都是放在一个Task中的,但是如果指定了特殊的启动模式,那么就会出现同一个App的Activity出现在不同的任务栈中的情况,即会有任务栈中包含来自于不同App的Activity。 标准模式,在不指定启动模式的情况下都是以此种方式启动的。每次启动都会创建一个新的Activity实例,覆盖在原有的Activity上,原有的Activity入栈。 测试如下:在FirstActivity中启动FirstActivity: 当只有一个FirstActivity时堆栈情况: 此种模式下,Activity在启动时会进行判断,如果当前的App的栈顶的Activity即正在活动的Activity就是将要启动的Activity,那么就不会创建新的实例,直接使用栈顶的实例。 测试,设置FirstActivity为此启动模式,多次点击FirstActivity中的启动FirstActivity的按钮查看堆栈情况: (其实点击按钮没有启动新Activity的动画就可以看出并没有启动新Activity) 大意就是: 对于使用singleTop启动或Intent.FLAG_ACTIVITY_SINGLE_TOP启动的Activity,当该Activity被重复启动(注意一定是re-launched,第一次启动时不会调用)时就会调用此方法。 且调用此方法之前会先暂停Activity也就是先调用onPause方法。 而且,即使是在新的调用产生后此方法被调用,但是通过getIntent方法获取到的依旧是以前的Intent,可以通过setIntent方法设置新的Intent。 方法参数就是新传递的Intent. 1.如果是同一个App中启动某个设置了此模式的Activity的话,如果栈中已经存在该Activity的实例,那么就会将该Activity上面的Activity清空,并将此实例放在栈顶。 测试:SecondActivity启动模式设为singleTask,启动三个Activity: 这个模式就很好记,以此模式启动的Activity会存放在一个单独的任务栈中,且只会有一个实例。 测试:SecondActivity启动模式设为singleInstance 结果: 显然,启动了两次ThirdActivity任务栈中就有两个实例,而SecondActivity在另外一个任务栈中,且只有一个。 在使用Intent启动一个Activity时可以设置启动该Activity的启动模式: 这个属性有很多,大致列出几个: 每个启动的Activity都在一个新的任务栈中 singleTop singleTask 用此种方式启动的Activity,在它启动了其他Activity后,会自动finish. 官方文档介绍如下: 这样看来的话,通俗易懂的讲,就是给每一个任务栈起个名,给每个Activity也起个名,在Activity以singleTask模式启动时,就检查有没有跟此Activity的名相同的任务栈,有的话就将其加入其中。没有的话就按照这个Activity的名创建一个任务栈。 测试:在App1中设置SecondActivity的taskAffinity为“gsq.test”,App2中的ActivityX的taskAffinity也设为“gsq.test” 任务栈信息如下: 结果很显然了。 测试:在上述基础上,在ActivityX中进行跳转到ActivityY,ActivityY不指定启动模式和taskAffinity。结果如下: 这样就没问题了,ActivityY在一个新的任务栈中,名称为包名。 这时从ActivityY跳转到SecondActivity,那应该是gsq.test任务栈只有SecondActivity,ActivityX已经没有了。因为其启动模式是singleTask,在启动它时发现已经有一个实例存在,就把它所在的任务栈上面的Activity都清空了并将其置于栈顶。 还有一点需要提一下,在上面,FirstActivity是App1的lunch Activity,但是由于SecondActivity并没有指定MAIN和LAUNCHER过滤器,故在FirstActivity跳转到SecondActivity时,按下home键,再点开App1,回到的是FirstActivity。 大致就先写这么多吧,好像有点长,废话有点多,估计也有错别字,不要太在意~~~

如何查看自己安卓手机的Android Device ID

首先呢楼主只说了硬件ID,我不清楚你是要找安卓基带版本号还是IMEI(移动设备身份码)。①如果要找安卓基带版本号,一般在设置里面最后一项都有一个“关于手机”,里面有手机详细的硬件信息。②如果楼主要找IMEI码,可以在拨号盘上按*#06#,每一个移动设备唯一对应15位IMEI码。

vivo手机androidid怎么查看

vivo手机androidid在GTalkServiceMonitor界面查看。1、点击电话,启动拨号界面,然后输入8255。2、输入之后即可进入GTalkServiceMonitor界面。3、在打开的ServiceMonitor界面找到DeviceID字段即可查看到自己手机的ID信息。

android的Flipper,程序不报错,不崩,但是屏幕没显示

public class MainActivity extends Activity implements OnGestureListener { private static final String TAG = "MainActivity"; private ViewFlipper viewFlipper; private GestureDetector detector; //手势检测 Animation leftInAnimation; Animation leftOutAnimation; Animation rightInAnimation; Animation rightOutAnimation; ImageView imageView; //放大缩小 所需 private static final int NONE = 0; private static final int DRAG = 1; private static final int ZOOM = 2; private int mode = NONE; private float oldDist; private Matrix matrix = new Matrix(); private Matrix savedMatrix = new Matrix(); private PointF start = new PointF(); private PointF mid = new PointF(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); viewFlipper = (ViewFlipper)findViewById(R.id.viewFlipper); detector = new GestureDetector(this); //往viewFlipper添加View viewFlipper.addView(getImageView(R.drawable.new_feature_1)); viewFlipper.addView(getImageView(R.drawable.new_feature_2)); viewFlipper.addView(getImageView(R.drawable.new_feature_3)); viewFlipper.addView(getImageView(R.drawable.new_feature_4)); viewFlipper.addView(getImageView(R.drawable.new_feature_5)); viewFlipper.addView(getImageView(R.drawable.new_feature_6)); //动画效果 leftInAnimation = AnimationUtils.loadAnimation(this, R.anim.left_in); leftOutAnimation = AnimationUtils.loadAnimation(this, R.anim.left_out); rightInAnimation = AnimationUtils.loadAnimation(this, R.anim.right_in); rightOutAnimation = AnimationUtils.loadAnimation(this, R.anim.right_out); } private ImageView getImageView(int id){ imageView = new ImageView(this); imageView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { Toast.makeText(MainActivity.this, imageView.getImageMatrix().toString(), Toast.LENGTH_SHORT).show(); return false; } }); imageView.setImageResource(id); viewFlipper.getChildAt(id); return imageView; } @Override public boolean onTouchEvent(MotionEvent event) { Log.i("onTouchEvent", "onTouchEvent"); return this.detector.onTouchEvent(event); //touch事件交给手势处理。 } @Override public boolean onDown(MotionEvent e) { // TODO Auto-generated method stub return false; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { Log.i(TAG, "e1="+e1.getX()+" e2="+e2.getX()+" e1-e2="+(e1.getX()-e2.getX()));if(e1.getX()-e2.getX()>120){ viewFlipper.setInAnimation(leftInAnimation); viewFlipper.setOutAnimation(leftOutAnimation); viewFlipper.showNext();//向右滑动 return true; }else if(e1.getX()-e2.getY()<-120){ viewFlipper.setInAnimation(rightInAnimation); viewFlipper.setOutAnimation(rightOutAnimation); viewFlipper.showPrevious();//向左滑动 return true; } return false; } @Override public void onLongPress(MotionEvent e) { // TODO Auto-generated method stub } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { // TODO Auto-generated method stub return false; } @Override public void onShowPress(MotionEvent e) { // TODO Auto-generated method stub } @Override public boolean onSingleTapUp(MotionEvent e) { // TODO Auto-generated method stub return false; }}

在手机里检测到软件有androidbenign会不会被监控?

相信大家在电视剧里面都看到了那种通过手机,进行监控你的戏码。但是被监控的人都是一些“大人物”,对于我们这种普通老百姓来说没有什么关系。但是在13年的时候,在美国就爆出了一个事件。就是说美国的NSA就每天获取了上百万的用户的用户记录,以及通过苹果、微软等巨头公司进行监控公民的聊天记录,图片等。大家这才意识到一个问题,原来这种监控也可能会发生在自己的身上。对于手机监控,到底会通过哪些渠道进行监控呢?1:通过GPS,一个导航系统。它的定位精确度很高的,我们平时给朋友发定位,使用打车软件等,都需要GPS的协作。2:就是通过WiFi,因为你打开WiFi功能就可以对你进行定位了。就是说你打开WiFi这项功能的时候,就会把你附近的WiFi检测出来,而每个WiFi都会有一个地址,所以对你进行定位就很容易了。3:就是通过基站,只要你的手机有信号,就会自动的连接上离你信号最强的一个基站,而通过这种方式就可以查到你的位置。那么就会有人想问了,那我要是关机了,别人还可以监控我吗?就是说如果你的手机被移植进了一个“赖皮”软件,那么就算说当你关机也是没用的,只是说是进入一个低电量的模式,看起来像关机了,但是其实你的一些主要的通讯芯片还是在工作运行,所以还是可以对你进行监听,甚至给你发短信,视频等。所以想想是不是都觉得有些可怕。那么手机的SIM卡拔掉了?还会被监控吗?其实你的手机只要是开着的就会连接基站的信息,然后再识别SIM卡,,所以就算没有SIM卡,别人只能说是不能直接监控你,但是会通过间接的刚上,关联手机的ID,或者曾经在哪里开过机等方式,追踪到和你。出现这5种情况,说明你的手机有可能被监控了。第一就是:手机不是自己在商店卖的,或者手机丢了然后又找回来了(很有可能被移植进了什么东西)。第二就是:手机有时候会卡,反应不灵敏。第三:就是在手机的通讯录里面会出现一些根本就不认识的号码,第四:就是通话费用暴涨(就是说你发短信或者收到短信都会发给“监控者”),第五:SIM卡卡通了第三方通话的服务。看到这些情况,你可能很想问,那应该怎么办,别着急,两点告诉你怎么做。第一你要加强自己的安全意识,就是说不要去下一些不正规的软件,以及安装一些不清楚的应用等。第二个就是“虚拟定位”这种方式来迷惑监控者。

android 平台的gpu的 flops怎么测

Android Studio报错,求助大神

可能是,griadle.app中API设置与sdk不匹配,或者引入了相同的包

Android 重学系列 ion驱动源码浅析

上一篇文章,在解析初始化GraphicBuffer中,遇到一个ion驱动,对图元进行管理。首先看看ion是怎么使用的: 我们按照这个流程分析ion的源码。 如果对ion使用感兴趣,可以去这篇文章下面看 https://blog.csdn.net/hexiaolong2009/article/details/102596744 本文基于Android的Linux内核版本3.1.8 遇到什么问题欢迎来本文讨论 https://www.jianshu.com/p/5fe57566691f 什么是ion?如果是音视频,Camera的工程师会对这个驱动比较熟悉。最早的GPU和其他驱动协作申请一块内存进行绘制是使用比较粗暴的共享内存。在Android系统中使用的是匿名内存。最早由三星实现了一个Display和Camera共享内存的问题,曾经在Linux社区掀起过一段时间。之后各路大牛不断的改进之下,就成为了dma_buf驱动。并在 Linux-3.3 主线版本合入主线。现在已经广泛的运用到各大多媒体开发中。 首先介绍dma_buf的2个角色,importer和exporter。importer是dma_buf驱动中的图元消费者,exporter是dma_buf驱动中的图元生产者。 这里借用大佬的图片: ion是基于dma_buf设计完成的。经过阅读源码,其实不少思路和Android的匿名内存有点相似。阅读本文之前就算不知道dma_buf的设计思想也没关系,我不会仔细到每一行,我会注重其在gralloc服务中的申请流程,看看ion是如何管理共享内存,为什么要抛弃ashmem。 我们先来看看ion的file_operation: 只有一个open和ioctl函数。但是没有mmap映射。因此mmap映射的时候一定其他对象在工作。 我们关注显卡英伟达的初始化模块。 文件:/ drivers / staging / android / ion / tegra / tegra_ion.c module_platform_driver实际上就是我之前经常提到过的module_init的一个宏,多了一个register注册到对应名字的平台中的步骤。在这里面注册了一个probe方法指针,probe指向的tegra_ion_probe是加载内核模块注册的时候调用。 先来看看对应的结构体: 再来看看对应ion内的堆结构体: 完成的事情如下几个步骤: 我们不关注debug模式。其实整个就是我们分析了很多次的方法。把这个对象注册miscdevice中。等到insmod就会把整个整个内核模块从dev_t的map中关联出来。 我们来看看这个驱动结构体: 文件:/ drivers / staging / android / ion / ion_heap.c 这里有四个不同堆会申请出来,我们主要来看看默认的ION_HEAP_TYPE_SYSTEM对应的heap流程。 其实真正象征ion的内存堆是下面这个结构体 不管原来的那个heap,会新建3个ion_system_heap,分别order为8,4,0,大于4为大内存。意思就是这个heap中持有一个ion_page_pool 页资源池子,里面只有对应order的2的次幂,内存块。其实就和伙伴系统有点相似。 还会设置flag为ION_HEAP_FLAG_DEFER_FREE,这个标志位后面会用到。 文件:/ drivers / staging / android / ion / ion_page_pool.c 在pool中分为2个链表一个是high_items,另一个是low_items。他们之间的区分在此时就是以2为底4的次幂为分界线。 文件:/ drivers / staging / android / ion / ion.c 因为打开了标志位ION_HEAP_FLAG_DEFER_FREE和heap存在shrink方法。因此会初始化两个回收函数。 文件:/ drivers / staging / android / ion / ion_heap.c 此时会创建一个内核线程,调用ion_heap_deferred_free内核不断的循环处理。不过由于这个线程设置的是SCHED_IDLE,这是最低等级的时间片轮转抢占。和Handler那个adle一样的处理规则,就是闲时处理。 在这个循环中,不断的循环销毁处理heap的free_list里面已经没有用的ion_buffer缓冲对象。 文件:/ drivers / staging / android / ion / ion_system_heap.c 注册了heap的销毁内存的方法。当系统需要销毁页的时候,就会调用通过register_shrinker注册进来的函数。 文件:/ drivers / staging / android / ion / ion_page_pool.c 整个流程很简单,其实就是遍历循环需要销毁的页面数量,接着如果是8的次幂就是移除high_items中的page缓存。4和0则销毁low_items中的page缓存。至于为什么是2的次幂其实很简单,为了销毁和申请简单。__free_pages能够整页的销毁。 文件:/ drivers / staging / android / ion / ion.c 主要就是初始化ion_client各个参数,最后把ion_client插入到ion_device的clients。来看看ion_client结构体: 核心还是调用ion_alloc申请一个ion缓冲区的句柄。最后把数据拷贝会用户空间。 这个实际上就是找到最小能承载的大小,去申请内存。如果8kb申请内存,就会拆分积分在0-4kb,4kb-16kb,16kb-128kb区间找。刚好dma也是在128kb之内才能申请。超过这个数字就禁止申请。8kb就会拆成2个4kb保存在第一个pool中。 最后所有的申请的page都添加到pages集合中。 文件:/ drivers / staging / android / ion / ion_page_pool.c 能看到此时会从 ion_page_pool冲取出对应大小区域的空闲页返回上层,如果最早的时候没有则会调用ion_page_pool_alloc_pages申请一个新的page。由于引用最终来自ion_page_pool中,因此之后申请之后还是在ion_page_pool中。 这里的处理就是为了避免DMA直接内存造成的缓存差异(一般的申请,默认会带一个DMA标志位)。换句话说,是否打开cache其实就是,关闭了则使用pool的cache,打开了则不使用pool缓存,只依赖DMA的缓存。 我们可以看另一个dma的heap,它是怎么做到dma内存的一致性. 文件: drivers / staging / android / ion / ion_cma_heap.c 能看到它为了能办到dma缓存的一致性,使用了dma_alloc_coherent创建了一个所有强制同步的地址,也就是没有DMA缓存的地址。 这里出现了几个新的结构体,sg_table和scatterlist 文件:/ lib / scatterlist.c 这里面实际上做的事情就是一件:初始化sg_table. sg_table中有一个核心的对象scatterlist链表。如果pages申请的对象数量<PAGE_SIZE/sizeof(scatterlist),每一项sg_table只有一个scatterlist。但是超出这个数字就会增加一个scatterlist。 用公式来说: 换句话说,每一次生成scatterlist的链表就会直接尽可能占满一页,让内存更好管理。 返回了sg_table。 初始化ion_handle,并且记录对应的ion_client是当前打开文件的进程,并且设置ion_buffer到handle中。使得句柄能够和buffer关联起来。 每当ion_buffer需要销毁,

android项目在手机上运行失败

是不是activity名字写错了?ccit.myjshb.MainActivity} does not exist. 说是这个ccit.myjshb.MainActivity不存在啊!你是复制之后没有修改包名吗?

如何在ANDROID JNI 的C++中打Log

//hwtest_log.h#include <stdio.h>#include <time.h>#include <<a href="https://www.baidu.com/s?wd=sys%2Ftypes.h&tn=44039180_cpr&fenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1Y3nvfvnyPBrj61PhnsnW-B0ZwV5Hcvrjm3rH6sPfKWUMw85HfYnjn4nH6sgvPsT6KdThsqpZwYTjCEQLGCpyw9Uz4Bmy-bIi4WUvYETgN-TLwGUv3EnWDYnHT4rHn1rHmsPWbsrHcvr0" target="_blank" class="baidu-highlight">sys/types.h</a>>#include <unistd.h>#ifdef HAVE_PTHREADS#include <pthread.h>#endif#include <stdarg.h>#include <android/log.h>#ifdef __cplusplus<a href="https://www.baidu.com/s?wd=extern&tn=44039180_cpr&fenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1Y3nvfvnyPBrj61PhnsnW-B0ZwV5Hcvrjm3rH6sPfKWUMw85HfYnjn4nH6sgvPsT6KdThsqpZwYTjCEQLGCpyw9Uz4Bmy-bIi4WUvYETgN-TLwGUv3EnWDYnHT4rHn1rHmsPWbsrHcvr0" target="_blank" class="baidu-highlight">extern</a> <a href="https://www.baidu.com/s?wd=%22C%22&tn=44039180_cpr&fenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1Y3nvfvnyPBrj61PhnsnW-B0ZwV5Hcvrjm3rH6sPfKWUMw85HfYnjn4nH6sgvPsT6KdThsqpZwYTjCEQLGCpyw9Uz4Bmy-bIi4WUvYETgN-TLwGUv3EnWDYnHT4rHn1rHmsPWbsrHcvr0" target="_blank" class="baidu-highlight">"C"</a> {#endif#ifndef HWTEST_LOG_TAG#define HWTEST_LOG_TAG NULL#endif#define HWTEST_LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, HWTEST_LOG_TAG, __VA_ARGS__)#define HWTEST_LOGI(...) __android_log_print(ANDROID_LOG_INFO, HWTEST_LOG_TAG, __VA_ARGS__)#define HWTEST_LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, HWTEST_LOG_TAG, __VA_ARGS__)#define HWTEST_LOGW(...) __android_log_print(ANDROID_LOG_WARN, HWTEST_LOG_TAG, __VA_ARGS__)#define HWTEST_LOGE(...) __android_log_print(ANDROID_LOG_ERROR, HWTEST_LOG_TAG, __VA_ARGS__)#ifdef __cplusplus}#endif其他文件中直接包含这个头文件12//调用,参数基本同printfHWTEST_LOGD("打印的信息");

android linphone中怎么添加g729协议

Found RTP audio format 101Found audio description format telephone-event for ID 101Found RTP video format 103Found video description format h263-1998 for ID 103Capabilities: us - 0x100 (g729), peer - audio=0x0 (nothing)/video=0x100000 (h263p)/text=0x0 (nothing), combined - 0x0 (nothing)Non-codec capabilities (dtmf): us - 0x1 (telephone-event|), peer - 0x1 (telephone-event|), combined - 0x1 (telephone-event|)[Apr 9 18:00:25] NOTICE[3813]: chan_sip.c:9187 process_sdp: **No compatible codecs**, not accepting this offer!SDPTo: <sip:5003@192.168.1.17>From: <sip:5004@192.168.1.17>;tag=z9hG4bK80811693Call-ID: 082004294635@10.0.2.15CSeq: 2 INVITEContact: <sip:5004@10.0.2.15:36252;transport=udp>Expires: 3600User-Agent: MySipdroid. !/2.4 beta/sdkAuthorization: Digest username="5004", realm="asterisk", nonce="6264308a", uri="sip:5003@192.168.1.17", algorithm=MD5, response="fb6dfb528d362657ef01458f96653adb"Content-Length: 137Content-Type: application/sdpv=0o=5004@192.168.1.17 0 0 IN IP4 10.0.2.15s=Session SIP/SDPc=IN IP4 10.0.2.15t=0 0m=audio 21000 RTP/AVPa=fmtp:18 annexb=no<------------->--- (13 headers 7 lines) ---Sending to 192.168.1.17:35370 (NAT)Using INVITE request as basis request - 082004294635@10.0.2.15Found peer "5004" for "5004" from 192.168.1.17:35370 == Using SIP RTP CoS mark 5Capabilities: us - 0x100 (g729), peer - audio=0x0 (nothing)/video=0x0 (nothing)/text=0x0 (nothing), combined - 0x0 (nothing)Non-codec capabilities (dtmf): us - 0x1 (telephone-event|), peer - 0x0 (nothing), combined - 0x0 (nothing)[Apr 10 12:01:05] NOTICE[3524]: chan_sip.c:9187 process_sdp: No compatible codecs, not accepting this offer!显示翻译结果core show translation Translation times between formats (in microseconds) for one second of data Source Format (Rows) Destination Format (Columns) g723 gsm ulaw alaw g726aal2 adpcm slin lpc10 g729 speex ilbc g726 g722 siren7 siren14 slin16 g719 speex16 testlaw g723 - - - - - - - - - - - - - - - - - - - gsm - - 1001 1001 3000 2000 1000 3000 3999 - 8999 3999 1001 - - 1002 - - 1001 ulaw - 2000 - 1 2001 1001 1 2001 3000 - 8000 3000 2 - - 3 - - 2 alaw - 2000 1 - 2001 1001 1 2001 3000 - 8000 3000 2 - - 3 - - 2 g726aal2 - 2999 1001 1001 - 2000 1000 3000 3999 - 8999 3999 1001 - - 1002 - - 1001 adpcm - 2000 2 2 2001 - 1 2001 3000 - 8000 3000 2 - - 3 - - 2 slin - 1999 1 1 2000 1000 - 2000 2999 - 7999 2999 1 - - 2 - - 1 lpc10 - 2999 1001 1001 3000 2000 1000 - 3999 - 8999 3999 1001 - - 1002 - - 1001 g729 - 2999 1001 1001 3000 2000 1000 3000 - - 8999 3999 1001 - - 1002 - - 1001 speex - - - - - - - - - - - - - - - - - - - ilbc - 2998 1000 1000 2999 1999 999 2999 3998 - - 3998 1000 - - 1001 - - 1000 g726 - 2999 1001 1001 3000 2000 1000 3000 3999 - 8999 - 1001 - - 1002 - - 1001 g722 - 2000 2 2 2001 1001 1 2001 3000 - 8000 3000 - - - 1 - - 2 siren7 - - - - - - - - - - - - - - - - - - - siren14 - - - - - - - - - - - - - - - - - - - slin16 - 3000 1002 1002 3001 2001 1001 3001 4000 - 9000 4000 1000 - - - - - 1002 g719 - - - - - - - - - - - - - - - - - - - speex16 - - - - - - - - - - - - - - - - - - - testlaw - 2000 2 2 2001 1001 1 2001 3000 - 8000 3000 2 - - 3 - - -sip.conf[5004]type=friendusername=5004secret=5004host=dynamiccontext=testcontextnat=yesdisallow=allallow=g729qualify=yescallerid="919999121312"<5004>

如何用Delphi XE Android实现手机和wifi串行口模块通信

问一下,JWiFiManager和JWiFiInfo是从哪里引用?

如何用Delphi XE Android实现手机和wifi串行口模块通信

uses System.SysUtils, Androidapi.Helpers, Androidapi.JNIBridge, Androidapi.Jni.Net, Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.JavaTypes, FMX.Helpers.Android;function GetWIFIIP:string;varWFM:JObject;WifiManager:JWifiManager;WifiInfo:JWifiInfo;IP:Integer;begin WFM:=TAndroidHelper.Context.getSystemService(TJContext.JavaClass.WIFI_SERVICE); WifiManager:=TJWifiManager.Wrap((WFM as ILocalObject).GetObjectID); WifiInfo:=WifiManager.getConnectionInfo; IP:=WifiInfo.getIpAddress; Result:=Format("%d.%d.%d.%d",[Lo(IP),Hi(IP),Lo(IP shr 16),IP shr 24]);end;

如何用Delphi XE Android实现手机和wifi串行口模块通信

uses System.SysUtils,Androidapi.Helpers,Androidapi.JNIBridge,Androidapi.Jni.Net,Androidapi.JNI.GraphicsContentViewText,Androidapi.JNI.JavaTypes,FMX.Helpers.Android;function GetWIFIIP:string;varWFM:JObject;WifiManager:JWifiManager;WifiInfo:JWifiInfo;IP:Integer;beginWFM:=TAndroidHelper.Context.getSystemService(TJContext.JavaClass.WIFI_SERVICE);WifiManager:=TJWifiManager.Wrap((WFM as ILocalObject).GetObjectID);WifiInfo:=WifiManager.getConnectionInfo;IP:=WifiInfo.getIpAddress;Result:=Format("%d.%d.%d.%d",[Lo(IP),Hi(IP),Lo(IP shr 16),IP shr 24]);end;//安卓系统WIFI下获取本机IP

如何用Delphi XE Android实现手机和wifi串行口模块通信

uses System.SysUtils,Androidapi.Helpers,Androidapi.JNIBridge,Androidapi.Jni.Net,Androidapi.JNI.GraphicsContentViewText,Androidapi.JNI.JavaTypes,FMX.Helpers.Android;function GetWIFIIP:string;varWFM:JObject;WifiManager:JWifiManager;WifiInfo:JWifiInfo;IP:Integer;beginWFM:=TAndroidHelper.Context.getSystemService(TJContext.JavaClass.WIFI_SERVICE);WifiManager:=TJWifiManager.Wrap((WFM as ILocalObject).GetObjectID);WifiInfo:=WifiManager.getConnectionInfo;IP:=WifiInfo.getIpAddress;Result:=Format("%d.%d.%d.%d",[Lo(IP),Hi(IP),Lo(IP shr 16),IP shr 24]);end;//安卓系统WIFI下获取本机IP

android.riskware.agent.gxwcx是什么病毒

没见过,你还是用腾讯电脑管家查杀下吧腾讯电脑管家自主研发的TAV杀毒引擎已多次通过国际权威评测,获得VB100认证、西海岸Check Mark认证等,是目前国内杀毒软件中仅使用自主技术便获得国际认证最多的安全软件,也代表了中国自主杀毒引擎技术首次获得国际认可。

ios和android设计规范区别

根据android4,0规范与ios规范,android与ios主要的不容之处表现在:1.android4.0包括三个虚拟按键:返回、home和最近任务,而ios只有一个物理home按键,返回按钮一般放置在导航栏左上方。2.android的主要操作栏在屏幕上方包括:向上+图标+页面名称+主要操作+更多(次要操作),主要操作栏还提供视图切换功能。ios包括导航栏、工具栏、tab栏,导航栏包括返回+标题+主要操作,工具栏包括一些次要操作,tab栏承担页面视图切换的功能。3.android规定tab栏应在屏幕上方,主要操作栏下面,尽量不要放置在屏幕下方,防止与虚拟按键误操作,而ios的tab栏在屏幕下方。4.android长按会出现情境操作栏,对内容项进行选择及内容项的主要操作功能,而ios很少使用长按功能。5.在手势操作上,android可以向左滑动删除单条内容,或滑动屏幕切换不同视图,而ios向右滑动删除内容,并且提供摇一摇返回等功能。6.界面表现形式不同如:文本输入框、弹出框、选择器、操作按钮图标等。但是,可以看到,为了保持用户体验及平台的一致性,以及资源的可重复利用,两个平台在界面布局上应尽量统一,有些app也会打破这些差异性,好多android的app在布局上与ios相同。

iphone4越狱5.0.1 版本。 装了 AndroidLock XT安桌解锁汉化版 出现了这个exit dafe mode 求高手帮解开。在

楼主解决了吗?我也安装了该死的安卓解锁,怎么办?加qq 291294649

百度android地图如何获取地图中心点的经纬坐标

在百度地图的damo里面,一般是有注释,可以下载代码看下。这是百度地图SDK说明:http://developer.baidu.com/map/index.php?title=androidsdk

Android应用程序启动流程总结

AMS主要功能: AMS是Android中最核心的服务,主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作。还负责启动或杀死应用程序的进程。 WMS主要功能: 为所有窗口分配Surface。 管理Surface的显示顺序、尺寸、位置。 管理窗口动画。 输入系统相关:WMS是派发系统按键和触摸消息的最佳人选,当接收到一个触摸事件,它需要寻找一个最合适的窗口来处理消息。 PWS主要功能: PMS 用来管理跟踪所有应用APK,包括安装,卸载,解析,控制权限等。 SystemServer也是一个进程,包括AMS、PMS、WMS等等。 zygote意为“受精卵“。Android是基于Linux系统的,而在Linux中,所有的进程都是由init进程直接或者是间接fork出来的,zygote进程也不例外。 App进程是用户点击桌面icon时,通过Launcher进程请求SystemServer,再调用Zygote孵化的。 ①点击启动一个App,Launcher进程采用Binder IPC向ActivityManagerService发起startActivity请求; ②ActivityManagerService接收到请求后,向zygote进程发送创建进程的请求; ③Zygote进程fork出新的子进程,即App进程; ④App进程通过Binder IPC向sytem_server进程发起绑定Application请求; ⑤system_server进程在收到请求后,进行一系列准备工作后,再通过binder IPC向App进程发送scheduleLaunchActivity请求; ⑥App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息; ⑦主线程在收到Message后,通过发射机制创建目标Activity,并回调Activity.onCreate()等方法。 ⑧到此,App便正式启动,开始进入Activity生命周期,执行完onCreate/onStart/onResume方法,UI渲染结束后便可以看到App的主界面。 备注: Launcher,PMS,Zygote,App进程是三个独立的进程,相互通信就需要使用进程间通信机制。与Zygote通信是使用的socket通信,Launcher,PMS,App进程间使用的是Binder机制。

android广播接收的onReceive方法不执行,即接收不到广播的消息

有几种可能你可以考虑:1,看标题,你是要读取用户信息,有没有获得读取用户数据的权限?2,广播动作是否注册?

Android 重学系列 GraphicBuffer的诞生

经过上一篇对OpenGL es的解析,我们引出了在eglSwapBuffer时候会调用会调用两个关键的方法: 从上一篇openGL es分析可以得出,每一次当我们绘制完一次图元之后,surface做为生产者一方会在一个循环中一般依次完成如下内容: 对于生产者来说关键的是这四个步骤。不过openGL es把整个过程颠倒,每一次绘制上一帧,对于更加好理解,我把整个过程设置回Android常用的方式。我们分别来研究这几个函数做了什么。 遇到什么问题,欢迎来本文进行讨论 https://www.jianshu.com/p/3bfc0053d254 首先我们先不去深究细节,先对整个流程的源码流程有一个大体印象。因为图元的诞生不清楚,也看不懂其他原理。 文件:/ frameworks / native / opengl / libagl / egl.cpp 在lock函数实际上是把ANativeWindowBuffer的handle传进去进行锁定,同时传入了一个vaddr的地址,这个地址是做什么的呢?其实就是共享buffer中的图元存储的地址。 实际上上在lock的时候,并不是直接把buffer传下去,而是传递一个handle,一个ANativeWindowBuffer的句柄。 文件:/ frameworks / native / libs / gui / Surface.cpp 先介绍Surface的核心对象之一mSlot,这个对象是数组BufferSlot: 在这里面保存着几个很重要对象: 在这里先介绍一个重要的概念,每一个GraphicBuffer图元在不同的流程会分为5个状态都会在BufferState记录状态: 根据这些状态,在SF中对应的计数个数不一样,这些计数影响着SF是否需要调整整个mSlot的使用策略。 因此当我们需要进行调整,需要对mDequeueCount+mAcquireCount加入调整计算,这样才能知道一共有多少图元在缓冲队伍之外,才能正确的计算,是否应该调整BufferQueue.mSlot的策略。在图元缓冲队列初始化那一章中,能看到会计算mMaxAcquiredBufferCount和mMaxDequeuedBufferCount的数量,来控制每一个Layer的图元生产者的是否需要调整slot为新的GraphicBuffer腾出位置。 流程如下: 让我们重点关注SF的dequeueBuffer。 文件:/ frameworks / native / libs / gui / BufferQueueProducer.cpp 在这个过程中其实很简单,就是找到合适的空位,添加到活跃区间,设置标志位,最后发现为空则会新生成一个,最后返回的是mSlot对应位置的下标。而不会直接返回一个完整的GraphicBuffer,因为一个图元太大了,根本不可能通过Binder进行通信。 我们来看看waitForFreeSlotThenRelock是怎么从mSlot找到合适位置的图元插槽。 在这个过程中,很简单,直接返回一个GraphicBuffer对象。不是说GraphicBuffer很大,Binder没有办法传输吗?为什么这里又能返回到app进程呢?稍后解析。这里就能Surface就记录了对应index的GraphicBuffer。 流程如下: 核心有四个: 其实在这个阶段判断mQueue如果为空,直接加到mQueue的末尾。不为空,需要判断最后一个图元是否已经不需要显示了,如果是共享模式的图元,则关闭。不是,则会从Active区域移除,放到Free区域中,并且代替mQueue最后一个图元。否则还是放到mQueue末尾。 此时就是回调到消费者中的监听回调,具体做了什么之后再说。 文件:/ frameworks / native / opengl / libagl / egl.cpp 能看到GraphicBufferMapper调用以ANativeWindowBuffer的handle为线索unlock解锁图元映射。 在整个流程中,我们能够看到生产者生产涉及到的主要角色如下: Surface是面向应用客户端的图元生产者,BufferQueueProducer是面向SF服务端的图元生产者。其核心涉及实际是查找mSlot中有没有空闲的位置,让图元占用。但是真正进行消费的时候,需要设置到BufferItem的Vector中。 但是思考过没有,一个图元代表一帧的数据。一个屏幕常见的占用的内存1080 1920 4 早就超过了应用传输Binder的极限1040k.那么系统是怎么规避这个问题呢? 我们从dequeue步骤中能看到,每一次dequeue之后先回返回一个mSlot的下标,即使在这个步骤已经new了一个GraphicBuffer,他也不会返回GraphicBuffer。但是到了requestBuffer就能GraphicBuffer对象。为什么这么设计?就算是返回了GraphicBuffer对象,Binder会因为这个对象占用太大而报错。 系统是怎么办到的?而且在OpenGL es中eglSwapBuffers中,把framebuffer_t和ANativeWindowBuffer的bit属性关联起来,ANativeWindowBuffer又是怎么在跨进程通信初始化bit字段的? 接下来让我们专门来解析GraphicBuffer类。 文件:/ frameworks / native / include / ui / GraphicBuffer.h 先来看看其继承关系: GraphicBuffer继承于ANativeWindowBuffer和Flattenable,前者是在ANativeWindow中的图元缓冲,后者是Binder 传输时候的Parcel封装IBinder。但是这里里面的flattern和unflattern方法被重写了为自己的保存所有参数的方法。我们稍后再看。 文件:/ frameworks / native / libs / ui / GraphicBuffer.cpp 在初始化中有一个十分核心的类GraphicBufferAllocator,图元申请器。这个类真正在一个GraphicBuffer的壳内,通过allocate真正生成一个核心内存块。接着会调用GraphicBufferMapper. getTransportSize在Mapper中记录大小。请注意,allocate方法中有一个十分核心的参数handle。他是来自ANativeWindowBuffer: 文件:/ frameworks / native / libs / nativebase / include / nativebase / nativebase.h native_handle_t实际上是的GraphicBuffer的句柄。 让我们依次看看GraphicBufferAllocator和GraphicBufferMapper都做了什么。 文件: frameworks / native / libs / ui / GraphicBufferAllocator.cpp ANDROID_SINGLETON_STATIC_INSTANCE这个宏实际上就是一个单例:

如何检测 Android Cursor 泄漏

有一些泄漏在代码中难以察觉,但程序长时间运行后必然会出现异常。同时该方法同样适合于其他需要检测资源泄露的情况。 最近发现某蔬菜手机连接程序在查询媒体存储(MediaProvider)数据库时出现严重 Cursor 泄漏现象,运行一段时间后会导致系统中所有使用到该数据库的程序无法使用。另外在工作中也常发现有些应用有 Cursor 泄漏现象,由于需要长时间运行才会出现异常,所以有的此类 bug 很长时间都没被发现。但是一旦 Cursor 泄漏累计到一定数目(通常为数百个)必然会出现无法查询数据库的情况,只有等数据库服务所在进程死掉重启才能恢复正常。通常的出错信息如下,指出某 pid 的程序打开了 866 个 Cursor 没有关闭,导致了 exception:3634 3644 E JavaBinder: *** Uncaught remote exception! (Exceptions are not yet supported across processes.) 3634 3644 E JavaBinder: android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed. # Open Cursors=866 (# cursors opened by pid 1565=866) 3634 3644 E JavaBinder: at android.database.CursorWindow.(CursorWindow.java:104) 3634 3644 E JavaBinder: at android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:198) 3634 3644 E JavaBinder: at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:147) 3634 3644 E JavaBinder: at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:141) 3634 3644 E JavaBinder: at android.database.CursorToBulkCursorAdaptor.getBulkCursorDescriptor(CursorToBulkCursorAdaptor.java:143) 3634 3644 E JavaBinder: at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:118) 3634 3644 E JavaBinder: at android.os.Binder.execTransact(Binder.java:367) 3634 3644 E JavaBinder: at dalvik.system.NativeStart.run(Native Method) 1. Cursor 检测原理在Cursor 对象被 JVM 回收运行到 finalize() 方法的时候,检测 close() 方法有没有被调用,此办法在 ContentResolver 里面也得到应用。简化后的示例代码如下: 1import android.database.Cursor; 2import android.database.CursorWrapper; 3import android.util.Log; 4 5publicclass TestCursor extends CursorWrapper { 6privatestaticfinal String TAG = "TestCursor"; 7privateboolean mIsClosed = false; 8private Throwable mTrace; 910public TestCursor(Cursor c) { 11super(c); 12 mTrace = new Throwable("Explicit termination method "close()" not called"); 13 } 1415 @Override 16publicvoid close() { 17 mIsClosed = true; 18 } 1920 @Override 21publicvoid finalize() throws Throwable { 22try { 23if (mIsClosed != true) { 24 Log.e(TAG, "Cursor leaks", mTrace); 25 } 26 } finally { 27super.finalize(); 28 } 29 } 30 }然后查询的时候,把 TestCursor 作为查询结果返回给 APP:1returnnew TestCursor(cursor); // cursor 是普通查询得到的结果,例如从 ContentProvider.query() 该方法同样适合于所有需要检测显式释放资源方法没有被调用的情形,是一种通用方法。但在 finalize() 方法里检测需要注意优点:准确。因为该资源在 Cursor 对象被回收时仍没被释放,肯定是发生了资源泄露。缺点:依赖于 finalize() 方法,也就依赖于 JVM 的垃圾回收策略。例如某 APP 现在有 10 个 Cursor 对象泄露,并且这 10 个对象已经不再被任何引用指向处于可回收状态,但是 JVM 可能并不会马上回收(时间不可预测),如果你现在检查不能够发现问题。另外,在某些情况下就算对象被回收 finalize() 可能也不会执行,也就是不能保证检测出所有问题。关于 finalize() 更多信息可以参考《Effective Java 2nd Edition》的 Item 7: Avoid Finalizers2. 使用方法对于APP 开发人员从GINGERBREAD 开始 Android 就提供了 StrictMode 工具协助开发人员检查是否不小心地做了一些不该有的操作。使用方法是在 Activity 里面设置 StrictMode,下面的例子是打开了检查泄漏的 SQLite 对象以及 Closeable 对象(普通 Cursor/FileInputStream 等)的功能,发现有违规情况则记录 log 并使程序强行退出。 1import android.os.StrictMode; 2 3publicclass TestActivity extends Activity { 4privatestaticfinalboolean DEVELOPER_MODE = true; 5publicvoid onCreate() { 6if (DEVELOPER_MODE) { 7 StrictMode.setVMPolicy(new StrictMode.VMPolicy.Builder() 8 .detectLeakedSqlLiteObjects() 9 .detectLeakedClosableObjects() 10 .penaltyLog() 11 .penaltyDeath() 12 .build()); 13 } 14super.onCreate(); 15 } 16 } 对于framework 开发人员如果是通过 ContentProvider 提供数据库数据,在 ContentResolver 里面已有 CloseGuard 类实行类似检测,但需要自行打开(上例也是打开 CloseGuard):1 CloseGuard.setEnabled(true);更值得推荐的办法是按照本文第一节中的检测原理,在 ContentResolver 内部类 CursorWrapperInner 里面加入。其他需要检测类似于资源泄漏的,同样可以使用该检测原理。3. 容易出错的地方忘记调用 close() 这种低级错误没什么好说的,这种应该也占不小的比例。下面说说不太明显的例子。提前返回有时候粗心会犯这种错误,在 close() 调用之前就 return 了,特别是函数比较大逻辑比较复杂时更容易犯错。这种情况可以通过把 close() 放在 finally 代码块解决1privatevoid method() { 2 Cursor cursor = query(); // 假设query() 是一个查询数据库返回 Cursor 结果的函数3if (flag == false) { //!!提前返回4return; 5 } 6 cursor.close(); 7 } 类的成员变量假设类里面有一个在类全局有效的成员变量,在方法 A 获取了查询结果,后面在其他地方又获取了一次查询结果,那么第二次查询的时候就应该先把前面一个 Cursor 对象关闭。 1publicclass TestCursor { 2private Cursor mCursor; 3 4privatevoid methodA() { 5 mCursor = query(); 6 } 7 8privatevoid methodB() { 9//!!必须先关闭上一个 cursor 对象10 mCursor = query(); 11 } 12 }注意:曾经遇到过有人对 mCursor 感到疑惑,明明是同一个变量为什么还需要先关闭?首先 mCursor 是一个 Cursor 对象的引用,在 methodA 时 mCursor 指向了 query() 返回的一个 Cursor 对象 1;在 methodB() 时它又指向了返回的另外一个 Cursor 对象 2。在指向 Cursor 对象 2 之前必须先关闭 Cursor 对象 1,否则就出现了 Cursor 对象 1 在 finalize() 之前没有调用 close() 的情况。异常处理打开和关闭 Cursor 之间的代码出现 exception,导致没有跑到关闭的地方:1try { 2 Cursor cursor = query(); 3// 中间省略某些出现异常的代码4 cursor.close(); 5 } catch (Exception e) { 6//!!出现异常没跑到 cursor.close()7 }这种情况应该把 close() 放到 finally 代码块里面: 1 Cursor cursor = null; 2try { 3 cursor = query(); 4// 中间省略某些出现异常的代码 5 } catch (Exception e) { 6// 出现异常 7 } finally { 8if (cursor != null) 9 cursor.close(); 10 }4. 总结思考在finalize() 里面检测是可行的,且基本可以满足需要。针对 finalize() 执行时间不确定以及可能不执行的问题,可以通过记录目前打开没关闭的 Cursor 数量来部分解决,超过一定数目发出警告,两种手段相结合。还有没有其他检测办法呢?有,在 Cursor 构造方法以及 close() 方法添加 log,运行一段时间后检查 log 看哪个地方没有关闭。简化代码如下: 1import android.database.Cursor; 2import android.database.CursorWrapper; 3import android.util.Log; 4 5publicclass TestCursor extends CursorWrapper { 6privatestaticfinal String TAG = "TestCursor"; 7private Throwable mTrace; 8 9public TestCursor(Cursor c) { 10super(c); 11 mTrace = new Throwable("cusor opened here"); 12 Log.d(TAG, "Cursor " + this.hashCode() + " opened, stacktrace is: ", mTrace); 13 } 1415 @Override 16publicvoid close() { 17 mIsClosed = true; 18 Log.d(TAG, "Cursor " + this.hashCode() + " closed."); 19 } 20 }检查时看某个 hashCode() 的 Cursor 有没有调用过 close() 方法,没有的话说明资源有泄露。这种方法优点是同样准确,且更可靠。

22 AndroidBroadcast广播机制

广播(Broadcast)机制用于进程/线程间通信,广播分为广播发送和广播接收两个过程,其中广播接收者BroadcastReceiver便是Android四大组件之一。 BroadcastReceiver分为两类: 从广播发送方式可分为三类: 广播在系统中以BroadcastRecord对象来记录, 该对象有几个时间相关的成员变量. 广播注册,对于应用开发来说,往往是在Activity/Service中调用 registerReceiver() 方法,而Activity或Service都间接继承于Context抽象类,真正干活是交给ContextImpl类。另外调用getOuterContext()可获取最外层的调用者Activity或Service。 [ContextImpl.java] 其中broadcastPermission拥有广播的权限控制,scheduler用于指定接收到广播时onRecive执行线程,当scheduler=null则默认代表在主线程中执行,这也是最常见的用法 [ContextImpl.java] ActivityManagerNative.getDefault()返回的是ActivityManagerProxy对象,简称AMP. 该方法中参数有mMainThread.getApplicationThread()返回的是ApplicationThread,这是Binder的Bn端,用于system_server进程与该进程的通信。 [-> LoadedApk.java] 不妨令 以BroadcastReceiver(广播接收者)为key,LoadedApk.ReceiverDispatcher(分发者)为value的ArrayMap 记为 A 。此处 mReceivers 是一个以 Context 为key,以 A 为value的ArrayMap。对于ReceiverDispatcher(广播分发者),当不存在时则创建一个。 此处mActivityThread便是前面传递过来的当前主线程的Handler. ReceiverDispatcher(广播分发者)有一个内部类 InnerReceiver ,该类继承于 IIntentReceiver.Stub 。显然,这是一个Binder服务端,广播分发者通过rd.getIIntentReceiver()可获取该Binder服务端对象 InnerReceiver ,用于Binder IPC通信。 [-> ActivityManagerNative.java] 这里有两个Binder服务端对象 caller 和 receiver ,都代表执行注册广播动作所在的进程. AMP通过Binder驱动将这些信息发送给system_server进程中的AMS对象,接下来进入AMS.registerReceiver。 [-> ActivityManagerService.java] 其中 mRegisteredReceivers 记录着所有已注册的广播,以receiver IBinder为key, ReceiverList为value为HashMap。 在BroadcastQueue中有两个广播队列mParallelBroadcasts,mOrderedBroadcasts,数据类型都为ArrayList<broadcastrecord style="box-sizing: border-box;">:</broadcastrecord> mLruProcesses数据类型为 ArrayList<ProcessRecord> ,而ProcessRecord对象有一个IApplicationThread字段,根据该字段查找出满足条件的ProcessRecord对象。 该方法用于匹配发起的Intent数据是否匹配成功,匹配项共有4项action, type, data, category,任何一项匹配不成功都会失败。 broadcastQueueForIntent(Intent intent)通过判断intent.getFlags()是否包含FLAG_RECEIVER_FOREGROUND 来决定是前台或后台广播,进而返回相应的广播队列mFgBroadcastQueue或者mBgBroadcastQueue。 注册广播: 另外,当注册的是Sticky广播: 广播注册完, 另一个操作便是在广播发送过程. 发送广播是在Activity或Service中调用 sendBroadcast() 方法,而Activity或Service都间接继承于Context抽象类,真正干活是交给ContextImpl类。 [ContextImpl.java] [-> ActivityManagerNative.java] [-> ActivityManagerService.java] broadcastIntent()方法有两个布尔参数serialized和sticky来共同决定是普通广播,有序广播,还是Sticky广播,参数如下: broadcastIntentLocked方法比较长,这里划分为8个部分来分别说明。 这个过程最重要的工作是: BroadcastReceiver还有其他flag,位于Intent.java常量: 主要功能: 这个过主要处于系统相关的10类广播,这里不就展开讲解了. 这个过程主要是将sticky广播增加到list,并放入mStickyBroadcasts里面。 其他说明: AMS.collectReceiverComponents : 广播队列中有一个成员变量 mParallelBroadcasts ,类型为ArrayList<broadcastrecord style="box-sizing: border-box;">,记录着所有的并行广播。</broadcastrecord> 动态注册的registeredReceivers,全部合并都receivers,再统一按串行方式处理。 广播队列中有一个成员变量 mOrderedBroadcasts ,类型为ArrayList<broadcastrecord style="box-sizing: border-box;">,记录着所有的有序广播。</broadcastrecord> 发送广播过程: 处理方式: 可见不管哪种广播方式,都是通过broadcastQueueForIntent()来根据intent的flag来判断前台队列或者后台队列,然后再调用对应广播队列的scheduleBroadcastsLocked方法来处理广播; 在发送广播过程中会执行 scheduleBroadcastsLocked 方法来处理相关的广播 [-> BroadcastQueue.java] 在BroadcastQueue对象创建时,mHandler=new BroadcastHandler(handler.getLooper());那么此处交由mHandler的handleMessage来处理: 由此可见BroadcastHandler采用的是”ActivityManager”线程的Looper [-> BroadcastQueue.java] 此处mService为AMS,整个流程还是比较长的,全程持有AMS锁,所以广播效率低的情况下,直接会严重影响这个手机的性能与流畅度,这里应该考虑细化同步锁的粒度。

如何读取和修改 modem NVRAM-Android开发问答

android中的我用bindServie()的方式去启动服务,结果这个方法不返回,服务启动了,求解!

http://www.cnblogs.com/onlylittlegod/archive/2011/05/15/2046652.html希望这篇文章对你有帮助

Android四大组件之Activity(2)组件间通信

u2003u2003 MainActivity 通过 startActivityForResult 启动 MainActivity2 ,同时传递一个 Bundle 对象给 MainActivity2 ,在 MainActivity2 中通过 getIntent 获取到传递过来的 Bundle ,进而得到 MainActivity 传递过来的String 数据并打印。 u2003u2003在 MainActivity2 中通过 setResult 设置需要传递给 MainActivity 的 Bundle 数据,在 MainActivity 的 onActivityResult 函数中就可以得到相关的 Bundle 数据。 u2003u2003每一个Android应用都有一个 Application 对象,这个 Application 会贯穿整个Android应用,在其中定义的变量,它的生命周期也是和整个应用的生命周期一样。 u2003u2003在 MainActivity 中定义了一个 伴生变量 ,它相当于 Java中的静态变量 ,而在 MainActivity2 中可以获取此静态变量,并对其进行修改。 u2003u2003通过 Fragment 的 setArguments(bundle) 实现 Activity 想 Fragment 传值。 u2003u2003通过 onAttach(activity: Activity) 方法获得 activity 实例,直接调用 activity 中的方法获得数据。 u2003u2003 Service 的 onBind 方法需要返回一个 Binder 对象,而这个对象在 ServiceConnection.onServiceConnected 中可以获取,从而实现 Service 和 Activity 之间的通信。 u2003u2003 startService 时,传入参数 intent 可以携带部分参数给 Service ,我们可以在 Service 的 onStartCommand 方法中得到 startService 传递过来的 intent 数据。 u2003u2003在service中持有 callback 接口,并在binder中定义方法得到service的实例。activity中实现 ServiceConnection ,通过绑定启动service,这样会回调 ServiceConnection 接口的 onServiceConnected 方法,从而得到service实例,对service中的 callback 进行赋值,在service中可进行耗时操作并见数据通过callback接口,传递给activity进行其他操作。 除了上面说的常用方法外,还有很多其他方法,比如广播机制,事件总汇(eventbus)等。

Android跨进程通信

本文整理和引用他人的笔记,旨在个人复习使用。 参考链接: https://blog.csdn.net/fanleiym/article/details/83894399 https://github.com/274942954/AndroidCollection/blob/master/Docs/Android%E7%9F%A5%E8%AF%86%E7%82%B9%E6%B1%87%E6%80%BB.md#%E8%BF%9B%E7%A8%8B%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F https://www.kaelli.com/4.html https://carsonho.blog.csdn.net/article/details/73560642?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.edu_weight&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.edu_weight 默认情况下,一个app只会运行在一个进程中,进程名为app的包名。 1. 分散内存的占用 Android系统对每个应用进程的内存占用是有限制的,占用内存越大的进程,被系统杀死的可能性就越大。使用多进程可以减少主进程占用的内存,避免OOM问题,降低被系统杀死的概率。 2. 实现多模块 一个成熟的应用一定是多模块化的。项目解耦,模块化,意味着开辟新的进程,有独立的JVM,带来数据解耦。模块之间互不干预,团队并行开发,同时责任分工也很明确。 3. 降低程序奔溃率 子进程崩溃不会影响主进程的运行,能降低程序的崩溃率。 4. 实现一些特殊功能 比如可以实现推送进程,使得主进程退出后,能离线完成消息推送服务。还可以实现守护进程,来唤醒主进程达到保活目的。还可以实现监控进程专门负责上报bug,进而提升用户体验。 android:process 属性的值以冒号开头的就是 私有进程 ,否则就是 公有进程 。当然命名还需要符合规范,不能以数字开头等等。 1. 前台进程 2. 可见进程 3. 服务进程 4. 后台进程 5. 空进程 Android 会将进程评定为它可能达到的最高级别。另外服务于另一进程的进程其级别永远不会低于其所服务的进程。 创建新的进程时会创建新的Application对象,而我们通常在Application的onCreate方法中只是完成一些全局的初始化操作,不需要多次执行。 解决思路:获取当前进程名,判断是否为主进程,只有主进程的时候才执行初始化操作 获取当前进程名的两种方法: Application中判断是否是主进程(方法1例子): Serializable 和 Parcelable是数据序列化的两种方式,Android中只有进行序列化过后的对象才能通过intent和Binder传递。 通常序列化后的对象完成传输后,通过反序列化获得的是一个新对象,而不是原来的对象。 Serializable是java接口,位于java.io的路径下。Serializable的原理就是把Java对象序列化为二进制文件后进行传递。Serializable使用起来非常简单,只需直接实现该接口就可以了。 Parcelable是Google为了解决Serializable效率低下的问题,为Android特意设计的一个接口。Parcelable的原理是将一个对象完全分解,分解成可以传输的数据类型(如基本数据类型)再进行传递。 通常需要存到本地磁盘的数据就使用Serializable,其他情况就使用效率更高的Parcelable。 IPC 即 Inter-Process Communication (进程间通信)。Android 基于 Linux,而 Linux 出于安全考虑,不同进程间不能之间操作对方的数据,这叫做“进程隔离”。 每个进程的虚拟内存空间(进程空间)又被分为了 用户空间和内核空间 , 进程只能访问自身用户空间,只有操作系统能访问内核空间。 由于进程只能访问自身用户空间,因此在传统的IPC中,发送进程需要通过copy_from_user(系统调用)将数据从自身用户空间拷贝到内核空间,再由接受进程通过copy_to_user从内核空间复拷贝到自身用户空间,共需要拷贝2次,效率十分低下。Android采用的是Binder作为IPC的机制,只需复制一次。 Binder翻译过来是粘合剂,是进程之间的粘合剂。 Binder IPC通信的底层原理是 通过内存映射(mmap),将接收进程的用户空间映射到内核空间 ,有了这个映射关系,接收进程就能通过用户空间的地址获得内核空间的数据,这样只需发送进程将数据拷贝到内核空间就可完成通讯。 一次完整的Binder IPC通信: 从IPC的角度看,Binder是一种跨进程通信机制(一种模型),Binder 是基于 C/S 架构的,这个通信机制中主要涉及四个角色:Client、Server、ServiceManager和Binder驱动。 Client、Server、ServiceManager都是运行在用户空间的进程,他们通过系统调用(open、mmap 和 ioctl)来访问设备文件/dev/binder,从而实现与Binder驱动的交互。Binder驱动提供进程间通信的能力(负责完成一些底层操作,比如开辟数据接受缓存区等),是Client、Server和ServiceManager之间的桥梁。 Client、Server就是需要进行通信两个的进程,通信流程: 细心的你一定发现了,注册服务和获得服务本身就是和ServiceManager进行跨进程通信。其实和ServiceManager的通信的过程也是获取Binder对象(早已创建在Binder驱动中,携带了注册和查询服务等接口方法)来使用,所有需要和ServiceManager通信的进程,只需通过0号引用,就可以获得这个Binder对象了。 AIDL内部原理就是基于Binder的,可以借此来分析Binder的使用。 AIDL是接口定义语言,简短的几句话就能定义好一个复杂的、内部有一定功能的java接口。 先看看ICallBack.aidl文件,这里定义了一个接口,表示了服务端提供的功能。 被定义出来的java接口继承了IInterface接口,并且内部提供了一个Stub抽象类给服务端(相当于封装了一下,服务端只需继承这个类,然后完成功能的里面具体的实现)。 参考: https://www.cnblogs.com/sqchen/p/10660939.html (以下是添加了回调的最终实现,可以看参考链接一步一步来) 为需要使用的类,创建aidl文件。 系统会自动在main文件下生成aidl文件夹,并在该文件夹下创建相应目录。 在java相同路径下创建Student类,这里不能使用@Parcelize注解,否则会报错 创建IStudentService.aidl,定义了一个接口,该接口定义了服务端提供的功能。创建完后rebuild一下项目 (每次创建和修改定义接口文件都要rebuild一下) 创建在服务端的StudentService 可以看见有回调,说明客户端也提供了接口给服务端来回调(双向通信,此时客户端的变成了服务端),即ICallBack.aidl 客户端是通过Binder驱动返回的Binder调用StudentService里的具体实现方法 AIDL使用注意: Messenger可以在不同进程中传递 Message 对象,在Message中放入我们需要传递的数据,就可以轻松地实现数据的进程间传递了。Messenger 是一种轻量级的 IPC 方案,是对AIDL的封装,底层实现是 AIDL。 使用详见: https://blog.csdn.net/qq951127336/article/details/90678698

Android中mmap原理及应用简析

mmap是Linux中常用的系统调用API,用途广泛,Android中也有不少地方用到,比如匿名共享内存,Binder机制等。本文简单记录下Android中mmap调用流程及原理。mmap函数原型如下: 几个重要参数 返回值是void *类型,分配成功后,被映射成虚拟内存地址。 mmap属于系统调用,用户控件间接通过swi指令触发软中断,进入内核态(各种环境的切换),进入内核态之后,便可以调用内核函数进行处理。 mmap->mmap64->__mmap2->sys_mmap2-> sys_mmap_pgoff ->do_mmap_pgoff 而 __NR_mmap在系统函数调用表中对应的减值如下: 通过系统调用,执行swi软中断,进入内核态,最终映射到call.S中的内核函数:sys_mmap2 sys_mmap2最终通过sys_mmap_pgoff在内核态完成后续逻辑。 sys_mmap_pgoff通过宏定义实现 进而调用do_mmap_pgoff: get_unmapped_area用于为用户空间找一块内存区域, current->mm->get_unmapped_area一般被赋值为arch_get_unmapped_area_topdown, 先找到合适的虚拟内存(用户空间),几经周转后,调用相应文件或者设备驱动中的mmap函数,完成该设备文件的mmap,至于如何处理处理虚拟空间,要看每个文件的自己的操作了。 这里有个很关键的结构体 它是文件驱动操作的入口,在open的时候,完成file_operations的绑定,open流程跟mmap类似 先通过get_unused_fd_flags获取个未使用的fd,再通过do_file_open完成file结构体的创建及初始化,最后通过fd_install完成fd与file的绑定。 重点看下path_openat: 拿Binder设备文件为例子,在注册该设备驱动的时候,对应的file_operations已经注册好了, open的时候,只需要根根inode节点,获取到file_operations既可,并且,在open成功后,要回调file_operations中的open函数 open后,就可以利用fd找到file,之后利用file中的file_operations *f_op调用相应驱动函数,接着看mmap。 Binder机制中mmap的最大特点是一次拷贝即可完成进程间通信 。Android应用在进程启动之初会创建一个单例的ProcessState对象,其构造函数执行时会同时完成binder mmap,为进程分配一块内存,专门用于Binder通信,如下。 第一个参数是分配地址,为0意味着让系统自动分配,流程跟之前分子类似,先在用户空间找到一块合适的虚拟内存,之后,在内核空间也找到一块合适的虚拟内存,修改两个控件的页表,使得两者映射到同一块物力内存。 Linux的内存分用户空间跟内核空间,同时页表有也分两类,用户空间页表跟内核空间页表,每个进程有一个用户空间页表,但是系统只有一个内核空间页表。而Binder mmap的关键是:也更新用户空间对应的页表的同时也同步映射内核页表,让两个页表都指向同一块地址,这样一来,数据只需要从A进程的用户空间,直接拷贝拷贝到B所对应的内核空间,而B多对应的内核空间在B进程的用户空间也有相应的映射,这样就无需从内核拷贝到用户空间了。 binder_update_page_range完成了内存分配、页表修改等关键操作: 可以看到,binder一次拷贝的关键是,完成内存的时候,同时完成了内核空间跟用户空间的映射,也就是说,同一份物理内存,既可以在用户空间,用虚拟地址访问,也可以在内核空间用虚拟地址访问。 普通文件的访问方式有两种:第一种是通过read/write系统调访问,先在用户空间分配一段buffer,然后,进入内核,将内容从磁盘读取到内核缓冲,最后,拷贝到用户进程空间,至少牵扯到两次数据拷贝;同时,多个进程同时访问一个文件,每个进程都有一个副本,存在资源浪费的问题。 另一种是通过mmap来访问文件,mmap()将文件直接映射到用户空间,文件在mmap的时候,内存并未真正分配,只有在第一次读取/写入的时候才会触发,这个时候,会引发缺页中断,在处理缺页中断的时候,完成内存也分配,同时也完成文件数据的拷贝。并且,修改用户空间对应的页表,完成到物理内存到用户空间的映射,这种方式只存在一次数据拷贝,效率更高。同时多进程间通过mmap共享文件数据的时候,仅需要一块物理内存就够了。 共享内存是在普通文件mmap的基础上实现的,其实就是基于tmpfs文件系统的普通mmap,有机会再分析,不再啰嗦。 Android中mmap原理及应用简析 仅供参考,欢迎指正

请问android进程的binder线程数量有限制吗?

在控制AndroidManifest.xml里面 android:syncable="false" android:multiprocess="false"

Android bind通信对性能影响

您好,您是想问Android bind通信对性能有什么影响事吗?为什么要使用Binder性能。主要影响的因素是拷贝次数:管道、消息队列、Socket的拷贝次书都是两次,性能不是很好;共享内存不需要拷贝,性能最好;Binder拷贝1次,性能仅次于共享内存;Linux 下传统的进程间通信原理与不足。内核程序在内核空间分配内存并开辟一块内核缓存区,发送进程通过copy_from_user函数将数据拷贝到到内核空间的缓冲区中。同样的,接收进程在接收数据时在自己的用户空间开辟一块内存缓存区,然后内核程序调用 copy_to_user() 函数将数据从内核缓存区拷贝到接收进程。这样数据发送进程和数据接收进程完成了一次数据传输,也就是一次进程间通信;其有两点不足之处:一次数据传递需要经历:用户空间 _> 内核缓存区 _> 用户空间,需要2次数据拷贝,效率不高。接收数据的缓存区由数据接收进程提供,但是接收进程并不知道需要多大的空间来存放将要传递过来的数据,因此只能开辟尽可能大的内存空间或者先调用API接收消息头来获取消息体的大小,浪费了空间或者时间。Binder更加稳定和安全。Binder是基于C/S架构的,技术上已经很成熟,稳定;共享内存没有分层,难以控制,并发同步访问临界资源时,可能还会产生死锁;从稳定性的角度讲,Binder是优于共享内存的。Android是一个开源的系统,并且拥有开放性的平台,市场上应用来源很广,因此安全性对于Android 平台而言极其重要。 传统的IPC接收方无法获得对方可靠的进程用户ID/进程ID(UID/PID),无法鉴别对方身份。Android 为每个安装好的APP分配了自己的UID, 通过进程的UID来鉴别进程身份。另外,Android系统中的Server端会判断UID/PID是否满足访问权限,而对外只暴露Client端,加强了系统的安全性。

Android Framework

Android Framework包含三个内容:服务端、客户端、linux驱动 Android Framework服务端包括两个很重要的类:WindowManagerService (WMS)、ActivityManagerService(AMS) 客户端包含以下类: Linux驱动和Framework相关的主要两个部分:画家SurfaceFlingeer和快递员Binder 每一个窗口都对应一个画Surface,SF主要是把各个surface显示到同一个屏幕,Binder则提供跨进程间的消息传递 从APK程序的运行过程中看,各个组件都在什么时候干什么样的活: ActivityThread从main()函数中就开始动起来,然后调用PrepareMainLooper()为UI线程创建一个消息快递通道即MessageQueue(), 接着创建ActivityThread对象,创建过程会创建一个消息装卸工Handler对象和一个快递员Binder对象,其中Binder负责接收远程Ams的IPC调用,接收到调用后让Handler把消息装到消息队列,UI线程很忙的都是异步的从消息队列中取出消息并执行相应的操作,比如start,stop、pause 然后UI线程让队列调用Looper.loop()方法进入消息循环体,进入后就会不断的从消息队列中读取并处理消息 当ActivityThread接收到Ams发送start某个Activity的快递后就会创建指定的Activity对象。Activity会先按窗户再去按玻璃和贴窗花,所以先创建PhoneWindow->DecorView->创建相应的View或ViewGroup。创建完成后就可以让大家欣赏了,调用WindowManager把界面显示到屏幕上,然后创建ViewRoot,然后调用Wms提供的远程接口添加一个窗口并显示到屏幕上。 接下来就是用户的操作,事件线程不断的把消息快递发到事件队列中去,然后事件分发线程秘书逐个取出消息,然后调用Wms中的相应函数处理该消息。 2.UI线程是什么? 一直在倾听用户的心声,所有的处理用户消息,以及绘制页面的工作都在该线程中完成

Android系统中的底层协议是如何实现的

Android系统底层协议解析作为目前全球最为广泛使用的移动操作系统之一,Android系统的位置不言自明。无论是在日常生活中,还是在商业领域中,都可以感受到Android系统带来的便利和创造力。而其中非常重要的一环便是Android系统的底层协议。Android系统的底层协议指的是一套能够实现系统内部数据传输和协调的规则和标准。它是由Android系统架构的各组件和级别之间形成的通信桥梁,能够促进系统之间的信息互换和共享。其中,Android系统最为重要的两个协议是:Binder和Socket。Binder协议是一种混合式IPC协议,它是Android系统中间件中最为重要的通信机制。在Binder机制的实现中,服务端通过LocalBinder和客户端通过Stub与代理Binder通信,最终可以在各个进程之间强制调用服务。Binder机制的运作原理主要是通过一个Binder对象,完成了在客户端和服务端之间的数据交换,无需开发人员自己实现IPC功能。它可以通过进程间通信(IPC)将进程之间的内存空间进行共享,使进程可以直接共享内存数据,而无需通过缓存提供一组抽象的接口。Socket协议则是介于应用层和传输层的传输层协议,它是一种电子管通信的方式,是安卓系统网络通讯的一种方式。Socket协议支持TCP/IP和UDP/IP等主流通信协议,具有稳定,可靠,通用性强等优点,也因此成为了Android系统中最为重要的一种通信机制。总的来说,Android系统的底层协议对于整个系统运行和通信起到了非常重要的作用。它们可以促进各组件之间的互动,使得系统的运作可以更加稳定快捷。因此,在设计移动应用程序的过程中,必须考虑到Android系统的底层协议,从而使程序在运行中更多情况下能够顺利完成各个层次的数据处理和传输。最终达到用户所期望的可靠性和效率。

为什么Android的Handler采用管道而不使用Binder

首先Handler不见得使用管道 (pipe), 事实上, 在Android M中实际上使用了 eventfd. 不过这不关键.要想比较好的理解为什么Handler使用管道而不是Binder, 我们可以从开发者的角度来思考一下: 在Looper中, 他要解决一个什么问题? 我自己本身不是很熟悉Looper这些概念, 粗粗看了下代码: 大约可以看成是消息循环(Message Loop)的样子吧. 其它线程发消息,Looper所在的线程接受并处理消息. 好吧, 开发者要解决的是一个生产者消费者问题. 一般说来对于生产者消费者问题我们需要考虑几个因素: buffer (用于存放"产品"的内存), 上锁 (保护对buffer的访问), 等待/唤醒:1. 生产者和消费者在同一个进程内, 所以无需考虑共享内存问题2. 上锁: posix mutex, 简单好用3. 等待/唤醒: 在没有消息时, 消费者不能忙等, 而应该阻塞 (block) 直到新消息到来 -这里的关键是3), 在Android/Linux中有很多方法可以用来等待/唤醒, 比如条件变量, Posix信号量 (Android不支持System V信号量), 消息队列, Unix socket , pipe, 甚至binder等等. 怎么选呢? Looper开发者的标准很可能是: 选较"轻"的. 于是他先选了pipe, 以后又发现eventfd更好 (很可能开发者不知道eventfd的存在, 毕竟eventfd还是比较新的系统调用).

如何在Android下使用Binder

  实现一个binder通信实例,需要经过以下步骤:  (1)获得ServiceManager的对象引用  (2)向ServiceManager注册新的Service  (3)在Client中通过ServiceManager获得Service对象引用  (3)在Client中发送请求,由Service返回结果。  下面看具体的代码如何实现。  3.1 libmyservice代码实现  (1)新建目录frameworks/base/myservice/libservice,进入该目录  view plain  $ cd frameworks/base  $ mkdir myservice  $ cd myservice  $ mkdir libmyservice  $ cd libmyservice  (2)编写libmyservice/myservic.h文件  view plain  #include <utils/threads.h>    #include <utils/RefBase.h>    #include <binder/IInterface.h>    #include <binder/BpBinder.h>    #include <binder/Parcel.h>        namespace android {    class MyService : public BBinder    {    mutable Mutex mLock;    int32_t mNextConnId;    public:    static int instantiate();    MyService();    virtual ~MyService();    virtual status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t);    };    }; //namespace  (2)编写libservice/myservice.cpp文件  view plain  #include "myservice.h"    #include <binder/IServiceManager.h>    #include <binder/IPCThreadState.h>        namespace android {        static struct sigaction oldact;    static pthread_key_t sigbuskey;        int MyService::instantiate()    {    LOGE("MyService instantiate");    // defaultServiceManager ()获得ServiceManager的对象引用,addService()可向ServiceManager注册新的服务    int r = defaultServiceManager()->addService(String16("android.myservice"), new MyService());    LOGE("MyService r = %d/n", r);    return r;    }        MyService::MyService()    {    LOGV("MyService created");    mNextConnId = 1;    pthread_key_create(&sigbuskey, NULL);    }        MyService::~MyService()    {    pthread_key_delete(sigbuskey);    LOGV("MyService destroyed");    }    // 每个系统服务都继承自BBinder类,都应重写BBinder的onTransact虚函数。当用户发送请求到达Service时,系统框架会调用Service的onTransact函数,该函数分析接收到的数据包,调用相应的接口函数处理请求    status_t MyService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)    {    switch(code)    {    case 0: {    pid_t pid = data.readInt32();    int num = data.readInt32();    num = num + 100;    reply->writeInt32(num);    return NO_ERROR;    }    break;    default:    return BBinder::onTransact(code, data, reply, flags);    }    }    }; //namespace  (3)编写libservice/Android.mk文件  view plain  # File: Android.mk  LOCAL_PATH := $(call my-dir)  include $(CLEAR_VARS)  LOCAL_SRC_FILES := myservice.cpp  LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)  LOCAL_SHARED_LIBRARIES := libutils libbinder  LOCAL_MODULE_TAGS := optional  LOCAL_PRELINK_MODULE := false  LOCAL_MODULE := libmyservice    include $(BUILD_SHARED_LIBRARY)  (4)编译libmyservice.so动态库  在android源码主目录下  view plain  $ source build/envsetup.sh    including device/htc/passion/vendorsetup.sh    including device/samsung/crespo4g/vendorsetup.sh    including device/samsung/crespo/vendorsetup.sh      $ mmm frameworks/base/myservice/libmyservice/  编译成功后生成文件:out/target/product/generic/system/lib/libmyservice.so

Android Binder Hook的实现

Binder Hook可以Hook掉 当前App 用到的系统Service服务。 以LocationManager为例,在获取一个LocationManager时分为两步。第一,获取IBinder对象;第二:IBinder对象通过asInterface()转化为LocationMangerService对象。最后初始化LocationManager,application层用到的都是LocationManager。 Hook的大致原理是:ServiceManager在获取某个Binder时,如果本地有缓存的Binder,就不再跨进程请求Binder了。我们可以在缓存中加入自己的Binder,使得ServiceManager查询本地缓存时得到一个自定义的CustomBinder对象,不再跨进程向系统请求。并且ILocationManager.Stub.asInterface(CustomBinder)方法返回我们自定义的Service对象。 这里面有两个地方需要用到自定义的对象。由于我们只Hook其中一部分的功能,其他功能还需要保留,所以用动态代理的方式创建自定义的Binder和自定义的Service。 在理解后面的内容前你需要了解这些知识点: Activity等类在获取系统Service时,都是调用getSystemService(serviceName)方法获取的。 Context 的 getSystemService() 方法调用了 SystemServiceRegistry 的 getSystemService() 方法。 SystemServiceRegistry 中有一个常量 SYSTEM_SERVICE_FETCHERS,这是一个Map。保存了ServiceName和对应的ServiceFetcher。ServicFetcher是用于创建具体Service的类。ServiceFetcher 的关键方法是 createService() 方法。 在 ServiceFetcher 的 createService() 方法中,调用了 ServiceManager.getService(name) 方法。以 LocationManager 对应的 ServiceFetcher 为例,它的createService()方法源码如下: 假如我们要修改 LocationManager 的 getLastKnownLocation() 方法(下文都是)。我们要做的就是让ServiceManager.getService("location")返回我们自定义的Binder。先看一下这个方法简化后的源码: sCache是一个Map,缓存了已经向系统请求过的Binder。如果我们需要让这个方法返回我们我们自己的binder,只需要事先往sCache中put一个自定义的Binder就行了。 在put之前,需要先创建出一个自定义的Binder。这个Binder在被 ILocationManager.Stub.asInterface 处理后,可以返回一个自定义的 LocationManagerService。 先看一下Binder的 asInterface() 的实现: 如果把 queryLocalInterface()方法返回一个自定义的Service,使得走if语句内部,不走else,那就算是Hook成功了。 假设我们想让系统的LocationManager返回的位置信息全是在天安门(116.23, 39.54)。那我们需要使得 LocatitionManagerService 的 getLastLocation() 方法 返回的全是 (116.23, 39.54)。 由于我们不能直接拿到系统的这个Service对象,可以先用反射的方式拿到系统的LocationManagerService。然后拦截getLastLocation()方法。 原生的Binder对象在调用 queryLocalInterface() 方法时会返回原生的Service对象。我们希望返回3.1中的自定义Service。所以这里拦截 queryLocalInterface() 方法。 有了自定义的Binder后,将它注入到ServiceManger的sCache变量中就完成Hook了~ 当onClick被调用的时候,Toast和Log都会显示天安门的坐标(116.23, 39.54)。证明Hook成功! 你甚至可以用Binder Hook的方式Hook掉 ActivityManager 。

android Service中自定义的Binder如何操作service中的handler

你描述不清出。至少我没看清楚。我尝试按照我自己对你描述的问题的理解来作答。binder.taskExecute()里头你没有涉及到“系统通知栏”的代码,所以当然没有变化!!!其次,你对于handler的理解有错误。我粗粗点下:thread A和thread B。A有B的Handler从而能和B通过Handler沟通。B也有A的Handler。当然,这个Handler都是在A或者B构造函数的时候传进去的(例如A exampleA = new A(B"s handler);)至于两个thread如何根据handler沟通?通过Message来沟通。线程A和B都有一个message queue(消息队列)。你构建一个message实例,然后将它加入到(此处具体化,例如放入B里头)线程的message queue里头中。这样线程(从队列里读一条处理一条就可以处理到你加入的Message,用Handler的handleMessage来处理)。(下面用aHandler,bHandler分别表示thread A的handler和B的hanler。)所以aHandler.sendEmptyMessage(int what)就是在添加一只带有what值的Message到A里头。bHandler....类似。所以,假设我现在是A,我为了告诉B一些东西,我就将我要告诉的B的东西(信息)放入到一个Message中,再将这个Message加入到B的消息队列中。(譬如你此问中,需要将“下载完成”“下载失败”这些信息添加进入message里头)。然后这个message怎么加入到B的消息的队列呢?这就是为什么要在A的构造函数里头传入B的Handler(bHandler)一个引用的原因。对于你的需求,Handler和Binder功能重复了。要么用Binder,要么用Handler。至于想在一个activity中调用自定义Binder里头的一个方法,不需要发送消息。只需要在需要调用的地方实例化一个Binder,然后通过这个实例.functionYouNeeded()就行。欢迎追问。

android中Boundservice和 IBinder 还有Binder这三者有什么联系和区别???

IBinder 就是绑定服务的方式启动服务,即服务可以通过Binder与启动service的类通信用的。

Android里用 C 语言编写的应用程序怎么通过 binder 节点通信

  我不懂你的意思,什么叫C程序?你要直接call binder driver么?如果只是想在native layer里通过servicemanager 注册一个service,然后用client 去call,我过去用过这个github的project去测android binder的readwrite performance:  mcr/Android-HelloWorldService · GitHub  然后你要想办法把service run 起来,我当时很hack,直接在zygote里改了代码,强行让helloworld在系统init的时候生成,但应该有命令行给你用的,你可以在看看。  而去直接去和binder driver做交互也没问题,只要做几个ioctl call,然后起两个process,一个注册一个节点,然后另一个去写message,但我没具体实现过,你玩玩应该就出来了,我感觉过程可能就像这个shmget的example差不多 IPC:Shared Memory。  此外,Binder这东西没什么独特的,它就是把最基本的message passing:一次传输要向kernel copy paste两次(一次sender 到kernel,一次kernel到receiver,每次都有context switch)和shared memory(kernel 和 userland share 一块 内存,不用context switch)合并起来了,就是receiver和kernel共享一块内存,而sender和kernel的交互必须要严格遵守message passing的原则,于是就取了一个折中,两次copy paste就变成了一次。  此外,service manager会在自己被生成的时候现将自己注册成binder里一个最特殊的service,其他程序想要进行ipc,就必须通过binder向service manager注册,在binder生成一个unique id,然后其他client向service manager查询时候就会得到那个id,于是就能通过binder与service process建立通讯。  我过去很喜欢玩这个,还很蛋疼的在minix上把binder原理实现了一遍,还有一个大神 老罗,他研究Android native非常透彻,你可以看他博客,能够对整个Android从init到Dalvik跑起来全部了解,我现在只知道他一个,因为他把Android source code全都读了一遍:老罗的Android之旅  

Android-zygote进程通信为什么不使用Binder?

首先,zygote进程在创建之后,才会创建SystemServer进程,而SystemServer进程是由zygote进程fock自身得到的,在fock自身的过程中,首先会结束自身的其他子线程,这样一来除了自身线程以外,其他线程都会被结束然后GC,而Binder是多线程模型,如果使用Binder进行进程间通信的话,则Binder线程也会被结束,而使用Binder进行进程间通信就无法做到。在fork新进程后,启动Zygote的4个Daemon线程,java堆整理,引用队列,以及析构线程。而在zygote通过fock自身创建子进程之后,如果该进程不是zygote进程,则会调用ZygoteInit.zygoteInit方法 而在zygoteInit方法中,才会对新创建的进程进行运行环境初始化工作以及启动Binder线程池。 其实Binder线程池的启动,是在SystemServer进程创建过程启动的,而在启动SystemServer的过程中,就需要传入ZygoteServer这个Zygote作为Server端的Socket,所以Zygote进程并不能使用Binder进程进行通信,而只能使用Socket。 而且,Binder线程池是在zygote进程启动之后启动的SystemServer进程中启动的,而SystemServer进程是由zygote进程fock自身得到的,所以zygote进程在启动之后,循环等待SystemServer进程的消息的时候,其实还没有Binder线程池。而且fock只支持当前线程的fock,而不支持多线程的fock,但是Binder又是一个多线程模型,在fock的时候会杀死多余的线程,这样一来,binder线程也就会被杀死,这样就没办法使用binder与SystemServer进程进行进程间通信。 fork 的行为是这样的:复制整个用户空间的数据(通常使用 copy-on-write 的策略,所以可以实现的速度很快)以及所有系统对象,然后仅复制当前线程到子进程。这里:所有父进程中别的线程,到了子进程中都是突然蒸发掉的

Android IPC机制 Binder

u2003每次 单向通信 拷贝次数为 1,server用户空间和内核空间通过内存映射可以直接交互。 u2003内核4M 上层限制1m-8k(传输Bitmap过大,就会崩溃的原因,Activity之间传输BitMap)。 u2003 《Android 基础组件 全家桶》 u2003 进程间通信IPC 为什么 Android 要采用 Binder 作为 IPC 机制? Android-Binder机制 Android Bander设计与实现 - 设计篇 Android跨进程通信:图文详解 Binder机制 原理 听说你Binder机制学的不错,来面试下这几个问题(一) Binder学习指南 Android中的Binder机制二(匿名Binder)

Android为什么选择binder

Binder主要能提供以下一些功能:  用驱动程序来推进进程间的通信。  通过共享内存来提高性能。  为进程请求分配每个进程的线程池。  针对系统中的对象引入了引用计数和跨进程的对象引用映射。  进程间同步调用。Android Binder设计与实现 – 设计篇:  目前linux支持的IPC包括传统的管道、System V IPC、即消息队列/共享内存/信号量,以及socket中只有socket支持Client-Server的通信方式。当然也可以在这些底层机制上架设一套协议来实现Client-Server通信,但这样增加了系统的复杂性,在手机这种条件复杂,资源稀缺的环境下可靠性也难以保证。另一方面是传输性能:  socket作为一款通用接口,其传输效率低,开销大,主要用在跨网络的进程间通信和本机上进程间的低速通信。消息队列和管道采用存储-转发方式,即数据先从发送方缓存区拷贝到内核开辟的缓存区中,然后再从内核缓存区拷贝到接收方缓存区,至少有两次拷贝过程。共享内存虽然无需拷贝,但控制复杂,难以使用。还有一点是出于安全性考虑:  Android作为一个开放式,拥有众多开发者的平台,应用程序的来源广泛,确保智能终端的安全是非常重要的。终端用户不希望从网上下载的程序在不知情的情况下偷窥隐私数据,连接无线网络,长期操作底层设备导致电池很快耗尽等等。传统IPC没有任何安全措施,完全依赖上层协议来确保。首先传统IPC的接收方无法获得对方进程可靠的UID/PID(用户ID/进程ID),从而无法鉴别对方身份。  Android为每个安装好的应用程序分配了自己的UID,故进程的UID是鉴别进程身份的重要标志。使用传统IPC只能由用户在数据包里填入UID/PID,但这样不可靠,容易被恶意程序利用。可靠的身份标记只有由IPC机制本身在内核中添加。其次传统IPC访问接入点是开放的,无法建立私有通道。比如命名管道的名称、system V的键值、socket的ip地址或文件名都是开放的,只要知道这些接入点的程序都可以和对端建立连接,不管怎样都无法阻止恶意程序通过猜测接收方地址获得连接。  基于以上原因,Android需要建立一套新的IPC机制来满足系统对通信方式,传输性能和安全性的要求,这就是Binder。Binder基于 Client-Server通信模式,传输过程只需一次拷贝,为发送发添加UID/PID身份,既支持实名Binder也支持匿名Binder,安全性高。面向对象的 Binder IPC:   面向对象思想的引入将进程间通信转化为通过对某个Binder对象的引用调用该对象的方法,而其独特之处在于Binder对象是一个可以跨进程引用的对象,它的实体位于一个进程中,而它的引用却遍布于系统的各个进程之中。最诱人的是,这个引用和java里引用一样既可以是强类型,也可以是弱类型,而且可以从一个进程传给其它进程,让大家都能访问同一Server,就像将一个对象或引用赋值给另一个引用一样。Binder模糊了进程边界,淡化了进程间通信过程,整个系统仿佛运行于同一个面向对象的程序之中。  面向对象只是针对应用程序而言,对于Binder驱动和内核其它模块一样使用C语言实现,没有类和对象的概念。Binder驱动为面向对象的进程间通信提供底层支持。

Android源码解析RPC系列(一)---Binder原理

看了几天的Binder,决定有必要写一篇博客,记录一下学习成果,Binder是Android中比较综合的一块知识了,目前的理解只限于JAVA层。首先Binder是干嘛用的?不用说,跨进程通信全靠它,操作系统的不同进程之间,数据不共享,对于每个进程来说,它都天真地以为自己独享了整个系统,完全不知道其他进程的存在,进程之间需要通信需要某种系统机制才能完成,在Android整个系统架构中,采用了大量的C/S架构的思想,所以Binder的作用就显得非常重要了,但是这种机制为什么是Binder呢?在Linux中的RPC方式有管道,消息队列,共享内存等,消息队列和管道采用存储-转发方式,即数据先从发送方缓存区拷贝到内核开辟的缓存区中,然后再从内核缓存区拷贝到接收方缓存区,这样就有两次拷贝过程。共享内存不需要拷贝,但控制复杂,难以使用。Binder是个折中的方案,只需要拷贝一次就行了。其次Binder的安全性比较好,好在哪里,在下还不是很清楚,基于安全性和传输的效率考虑,选择了Binder。Binder的英文意思是粘结剂,Binder对象是一个可以跨进程引用的对象,它的实体位于一个进程中,这个进程一般是Server端,该对象提供了一套方法用以实现对服务的请求,而它的引用却遍布于系统的各个进程(Client端)之中,这样Client通过Binder的引用访问Server,所以说,Binder就像胶水一样,把系统各个进程粘结在一起了,废话确实有点多。 为了从而保障了系统的安全和稳定,整个系统被划分成内核空间和用户空间 内核空间:独立于普通的应用程序,可以访问受保护的内存空间,有访问底层硬件设备的所有权限。 用户空间:相对与内核空间,上层运用程序所运行的空间就是用户空间,用户空间访问内核空间的唯一方式就是系统调用。一个4G的虚拟地址空间,其中3G是用户空间,剩余的1G是内核空间。如果一个用户空间想与另外一个用户空间进行通信,就需要内核模块支持,这个运行在内核空间的,负责各个用户进程通过Binder通信的内核模块叫做Binder驱动,虽然叫做Binder驱动,但是和硬件并没有什么关系,只是实现方式和设备驱动程序是一样的,提供了一些标准文件操作。 在写AIDL的时候,一般情况下,我们有两个进程,一个作为Server端提供某种服务,然后另外一个进程作为Client端,连接Server端之后,就 可以使用Server里面定义的服务。这种思想是一种典型的C/S的思想。值得注意的是Android系统中的Binder自身也是C/S的架构,也有Server端与Client端。一个大的C/S架构中,也有一个小的C/S架构。 先笼统的说一下,在整个Binder框架中,由系列组件组成,分别是Client、Server、ServiceManager和Binder驱动程序,其中Client、Server和ServiceManager运行在用户空间,Binder驱动程序运行内核空间。运行在用户空间中的Client、Server和ServiceManager,是在三个不同进程中的,Server进程中中定义了服务提供给Client进程使用,并且Server中有一个Binder实体,但是Server中定义的服务并不能直接被Client使用,它需要向ServiceManager注册,然后Client要用服务的时候,直接向ServiceManager要,ServiceManager返回一个Binder的替身(引用)给Client,这样Client就可以调用Server中的服务了。 场景 :进程A要调用进程B里面的一个draw方法处理图片。 分析 :在这种场景下,进程A作为Client端,进程B做为Server端,但是A/B不在同一个进程中,怎么来调用B进程的draw方法呢,首先进程B作为Server端创建了Binder实体,为其取一个字符形式,可读易记的名字,并将这个Binder连同名字以数据包的形式通过Binder驱动发送给ServiceManager,也就是向ServiceManager注册的过程,告诉ServiceManager,我是进程B,拥有图像处理的功能,ServiceManager从数据包中取出名字和引用以一个注册表的形式保留了Server进程的注册信息。为什么是以数据包的形式呢,因为这是两个进程,直接传递对象是不行滴,只能是一些描述信息。现在Client端进程A联系ServiceManager,说现在我需要进程B中图像处理的功能,ServiceManager从注册表中查到了这个Binder实体,但是呢,它并不是直接把这个Binder实体直接给Client,而是给了一个Binder实体的代理,或者说是引用,Client通过Binder的引用访问Server。分析到现在,有个关键的问题需要说一下,ServiceManager是一个进程,Server是另一个进程,Server向ServiceManager注册Binder必然会涉及进程间通信。当前实现的是进程间通信却又要用到进程间通信,这就好象蛋可以孵出鸡前提却是要找只鸡来孵蛋,确实是这样的,ServiceManager中预先有了一个自己的Binder对象(实体),就是那只鸡,然后Server有个Binder对象的引用,就是那个蛋,Server需要通过这个Binder的引用来实现Binder的注册。鸡就一只,蛋有很多,ServiceManager进程的Binder对象(实体)仅有一个,其他进程所拥有的全部都是它的代理。同样一个Server端Binder实体也应该只有一个,对应所有Client端全部都是它的代理。 我们再次理解一下Binder是什么?在Binder通信模型的四个角色里面;他们的代表都是“Binder”,一个Binder对象就代表了所有,包括了Server,Client,ServiceManager,这样,对于Binder通信的使用者而言,不用关心实现的细节。对Server来说,Binder指的是Binder实体,或者说是本地对象,对于Client来说,Binder指的是Binder代理对象,也就是Binder的引用。对于Binder驱动而言,在Binder对象进行跨进程传递的时候,Binder驱动会自动完成这两种类型的转换。 简单的总结一下,通过上面一大段的分析,一个Server在使用的时候需要经历三个阶段 1、定义一个AIDL文件 Game.aidl GameManager .aidl 2、定义远端服务Service 在远程服务中的onBind方法,实现AIDL接口的具体方法,并且返回Binder对象 3、本地创建连接对象 以上就是一个远端服务的一般套路,如果是在两个进程中,就可以进程通信了,现在我们分析一下,这个通信的流程。重点是GameManager这个编译生成的类。 从类的关系来看,首先接口GameManager 继承 IInterface ,IInterface是一个接口,在GameManager内部有一个内部类Stub,Stub继承了Binder,(Binder实现了IBinder),并且实现了GameManager接口,在Stub中还有一个内部类Proxy,Proxy也实现了GameManager接口,一个整体的结构是这样的 现在的问题是,Stub是什么?Proxy又是什么?在上面说了在Binder通信模型的四个角色里面;他们的代表都是“Binder”,一个Binder对象就代表了所有,包括了Server,Clinet,ServiceManager,为了两个进程的通信,系统给予的内核支持是Binder,在抽象一点的说,Binder是系统开辟的一块内存空间,两个进程往这块空间里面读写数据就行了,Stub从Binder中读数据,Proxy向Binder中写数据,达到进程间通信的目的。首先我们分析Stub。 Stub 类继承了Binder ,说明了Stub有了跨进程传输的能力,实现了GameManager接口,说明它有了根据游戏ID查询一个游戏的能力。我们在bind一个Service之后,在onServiceConnecttion的回调里面,就是通过asInterface方法拿到一个远程的service的。 asInterface调用queryLocalInterface。 mDescriptor,mOwner其实是Binder的成员变量,Stub继承了Binder,在构造函数的时候,对着两个变量赋的值。 如果客户端和服务端是在一个进程中,那么其实queryLocalInterface获取的就是Stub对象,如果不在一个进程queryLocalInterface查询的对象肯定为null,因为不同进程有不同虚拟机,肯定查不到mOwner对象的,所以这时候其实是返回的Proxy对象了。拿到Stub对象后,通常在onServiceConnected中,就把这个对象转换成我们多定义AIDL接口。 比如我们这里会转换成GameManager,有了GameManager对象,就可以调用后querryGameById方法了。如果是一个进程,那直接调用的是自己的querryGameById方法,如果不是一个进程,那调用了就是代理的querryGameById方法了。 看到其中关键的一行是 mRemote就是一个IBinder对象,相对于Stub,Proxy 是组合关系(HAS-A),内部有一个IBinder对象mRemote,Stub是继承关系(IS-A),直接实现了IBinder接口。 transact是个native方法,最终还会回掉JAVA层的onTransact方法。 onTransact根据调用号(每个AIDL函数都有一个编号,在跨进程的时候,不会传递函数,而是传递编号指明调用哪个函数)调用相关函数;在这个例子里面,调用了Binder本地对象的querryGameById方法;这个方法将结果返回给驱动,驱动唤醒挂起的Client进程里面的线程并将结果返回。于是一次跨进程调用就完成了。 ***Please accept mybest wishes for your happiness and success ! ***

Carson带你学Android:全面剖析Binder跨进程通信原理

从而全方位地介绍 Binder ,希望你们会喜欢。 在本文的讲解中,按照 大角度 -> 小角度 去分析 Binder ,即: 从而全方位地介绍 Binder ,希望你们会喜欢。 在讲解 Binder 前,我们先了解一些 Linux 的基础知识 具体请看文章: 操作系统:图文详解 内存映射 Binder 跨进程通信机制 模型 基于 Client - Server 模式 此处重点讲解 Binder 驱动作用中的跨进程通信的原理: 原因: 所以,原理图可表示为以下: 所以,在进行跨进程通信时,开发者只需自定义 Client & Server 进程 并 显式使用上述3个步骤,最终借助 Android 的基本架构功能就可完成进程间通信 注册服务后, Binder 驱动持有 Server 进程创建的 Binder 实体 此时, Client 进程与 Server 进程已经建立了连接 Client 进程 根据获取到的 Service 信息( Binder 代理对象),通过 Binder 驱动 建立与 该 Service 所在 Server 进程通信的链路,并开始使用服务 步骤1: Client 进程 将参数(整数a和b)发送到 Server 进程 步骤2: Server 进程根据 Client 进要求 调用 目标方法(即加法函数) 步骤3: Server 进程 将目标方法的结果(即加法后的结果)返回给 Client 进程 对比 Linux ( Android 基于 Linux )上的其他进程通信方式(管道、消息队列、共享内存、 信号量、 Socket ), Binder 机制的优点有: 特别地,对于从模型结构组成的Binder驱动来说: 不定期分享关于 安卓开发 的干货,追求 短、平、快 ,但 却不缺深度 。

Android通信方式篇(七)-Binder机制(Native层(下))

本篇文章针对向ServiceManager注册服务 和 获取服务两个流程来做总结。在这两个过程中,ServiceManager都扮演的是服务端,与客户端之间的通信也是通过Binder IPC。 在此之前先了解下Binder的进程与线程的关系: 用户空间 :ProcessState描述一个进程,IPCThreadState对应一个进程中的一个线程。 内核空间 :binder_proc描述一个进程,统一由binder_procs全局链表保存,binder_thread对应进程的一个线程。 ProcessState与binder_proc是一一对应的。 Binder线程池 :每个Server进程在启动时会创建一个binder线程池,并向其中注册一个Binder线程;之后Server进程也可以向binder线程池注册新的线程,或者Binder驱动在探测到没有空闲binder线程时会主动向Server进程注册新的的binder线程。对于一个Server进程有一个最大Binder线程数限制15,(#define DEFAULT_MAX_BINDER_THREADS 15)。对于所有Client端进程的binder请求都是交由Server端进程的binder线程来处理的。我的理解是:binder线程是进程进行binder ipc时的一条数据处理路径。 MediaPlayerService向ServiceManager注册过程如下: 相关类: 整个过程总结如下: 1 获取BpServiceManager 与 BpBinder 由defaultServiceManager()返回的是BpServiceManager,同时会创建ProcessState对象和BpBinder对象。然后通过BpBinder执行transact,把真正工作交给IPCThreadState来处理。 2 BpBinder transact Binder代理类调用transact()方法,真正工作还是交给IPCThreadState来进行transact工作。 3 通过IPCThreadState 包装并转换数据并进行transact事务处理 每个线程都有一个IPCThreadState,每个IPCThreadState中都有一对Parcel变量:mIn、mOut。相当于两根数据管道: 最后执行talkWithDriver。 writeTransactionData:将BC Protocol + binder_transaction_data结构体 写入mOut, 然后执行waitForResponse: 由talkWithDriver将数据进一步封装到binder_write_read结构体,通过ioctl(BINDER_WRITE_READ)与驱动通信。同时等待驱动返回的接收BR命令,从mIn取出返回的数据。 mIn包装的数据结构(注册服务handle = 0 ,code 为ADD_SERVICE_TRANSACTION): 4 Binder Driver 把binder_write_read结构体write_buffer里数据取出来,分别得到BC命令和封装好数据的事务binder_transaction_data, 然后根据handler,在当前binder_proc中,找到相应的binder_ref,由binder_ref再找到目标binder_node实体,由目标binder_node再找到目标进程binder_proc。然后就是插入数据:当binder驱动可以找到合适的线程,就会把binder_transaction节点插入到servciemanager的线程的todo队列中,如果找不到合适的线程,就把节点之间插入servciemanager的binder_proc的todo队列。 5 ServiceManager 经过Binder Driver的处理,数据已经到了ServiceManager进程,在BR_TRANSACTION的引导下,在binder_loop()中执行binder_parser()取出数据,执行do_add_service()操作,最终向 svcinfo 列表中添加已经注册的服务(没有数据的返回)。最后发送 BR_REPLY 命令唤醒等待的线程,通知注册成功。结束MediaPlayerService进程 waitForResponse()的状态,整个注册过程结束。 获取服务的过程与注册类似,首先 ServiceManager 向 Binder 驱动发送 BC_TRANSACTION 命令携带 CHECK_SERVICE_TRANSACTION 命令,同时获取服务的线程进入等待状态 waitForResponse()。Binder 驱动收到请求命令向 ServiceManager 的发送 BC_TRANSACTION 查询已注册的服务,会区分请求服务所属进程情况。 查询到直接响应 BR_REPLY 唤醒等待的线程。若查询不到将与 binder_procs 链表中的服务进行一次通讯再响应。 以startService为例来简单总结下执行流程: 3.1 从方法执行流程来看: Client : 1 AMP.startService 标记方法以及通过Parcel包装数据; 2 BinderProxy.transact 实际调用native的 android_os_BinderProxy_transact 传递数据; 3 获取BpServiceManager 与 BpBinder 同时会创建ProcessState。然后通过BpBinder执行transact,把真正工作交给IPCThreadState来处理; 4 IPC.transact 主要执行writeTransactionData,将上层传来的数据重新包装成binder_transaction_data,并将BC Protocol + binder_transaction_data结构体 写入mOut; 5 IPC waitForResponse talkWithDriver + 等待返回数据; 6 talkWithDriver 将数据进一步封装成binder_write_read,通过ioctl(BINDER_WRITE_READ)与驱动通信; Kernel : 7 binder ioctl 接收BINDER_WRITE_READ ioctl命令; 8 binder_ioctl_write_read 把用户空间数据ubuf拷贝到内核空间bwr; 9 binder_thread_write 当bwr写缓存有数据,则执行binder_thread_write;当写失败则将bwr数据写回用户空间并退出; 10 binder_transaction 找到目标进程binder_proc并插入数据到目标进程的线程todo队列,最终执行到它 时,将发起端数据拷贝到接收端进程的buffer结构体; 11 binder_thread_read 根据binder_transaction结构体和binder_buffer结构体数据生成新的binder_transaction_data结构体,写入bwr的read_buffer,当bwr读缓存有数据,则执行binder_thread_read;当读失败则再将bwr数据写回用户空间并退出;最后,把内核数据bwr拷贝到用户空间ubuf。 12 binder_thread_write + binder_ioctl BR命令和数据传递 Server: 13 IPC.executeCommand 解析kernel传过来的binder_transaction_data数据,找到目标BBinder并调用其transact()方法; 14 IPC.joinThreadPool 采用循环不断地执行getAndExecuteCommand()方法, 处理事务。当bwr的读写buffer都没有数据时,则阻塞在binder_thread_read的wait_event过程. 另外,正常情况下binder线程一旦创建则不会退出. 15 BBinder.transact 到Binder.exeTransact 调用 AMN.onTransact 16 AMN.onTransact 把数据传递到AMS.starService去执行 17 AMS.starService Server处理了Client的请求了 然后原路replay回去,talkWithDriver 到Kernel ,然后找到Client进程,把数据拷贝到read_buffer里,最终唤醒IPC,把反馈传递回AMP.startService。完成启动服务。 3.2 从通信协议流程来看: 非oneWay: oneway: oneway与非oneway区别: 都是需要等待Binder Driver的回应消息BR_TRANSACTION_COMPLETE. 主要区别在于oneway的通信收到BR_TRANSACTION_COMPLETE则返回,而不会再等待BR_REPLY消息的到来. 另外,oneway的binder IPC则接收端无法获取对方的pid. 3.3 从数据流来看 从用户空间开始: 进入驱动后: 回到用户空间: 参考: http://gityuan.com/2016/09/04/binder-start-service/ http://gityuan.com/2015/11/28/binder-summary/ http://gityuan.com/2015/11/14/binder-add-service/ http://gityuan.com/2015/11/15/binder-get-service/

如何在Android下使用Binder

1概述Binder是基于OpenBinder,在Android系统上使用的进程间通信机制。Binder基于Client-Server通信模式,本质上可以理解为它实现了Client对Server对象的远程调用。比如,有某个binder对象A位于Server中,该对象提供了一套函数用以实现对服务的请求,而在一个或多个Client中包含对象A的引用,Client通过该引用可以调用远端Server中对象A的接口函数,这种远端调用对Client而言,与调用本地对象并无区别。2 通信模型Binder机制定义了四个组件,分别是Client,Server,ServiceManager和binder驱动,其中Client,Server,ServiceManager运行于用户空间,binder驱动运行于内核空间。binder驱动binder驱动是内核中的一个字符设备驱动/dev/binder,它是整个Binder通信机制的核心。Client,Server,ServiceManager通过open()和ioctl()文件操作函数与binder驱动进行通信,从而实现了Client向Server发送请求,Server处理请求并返回结果到Client。具体来说,它负责进程之间Binder通信的建立,Binder在进程之间的传递,Binder引用计数管理,数据包在进程之间的传递和交互等一系列底层支持。ServiceManagerServiceManager是一个守护进程,负责管理服务,即所有的Server需要向ServiceManager注册服务。同时,ServiceManager向Client提供查询和获取Server的接口。3 binder通信实例实现一个binder通信实例,需要经过以下步骤:(1)获得ServiceManager的对象引用(2)向ServiceManager注册新的Service(3)在Client中通过ServiceManager获得Service对象引用(3)在Client中发送请求,由Service返回结果。下面看具体的代码如何实现。3.1 libmyservice代码实现(1)新建目录frameworks/base/myservice/libservice,进入该目录view plain$ cd frameworks/base $ mkdir myservice $ cd myservice $ mkdir libmyservice $ cd libmyservice (2)编写libmyservice/myservic.h文件view plain#include <utils/threads.h> #include <utils/RefBase.h> #include <binder/IInterface.h> #include <binder/BpBinder.h> #include <binder/Parcel.h> namespace android { class MyService : public BBinder { mutable Mutex mLock; int32_t mNextConnId; public: static int instantiate(); MyService(); virtual ~MyService(); virtual status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t); }; }; //namespace (2)编写libservice/myservice.cpp文件view plain#include "myservice.h" #include <binder/IServiceManager.h> #include <binder/IPCThreadState.h> namespace android { static struct sigaction oldact; static pthread_key_t sigbuskey; int MyService::instantiate() { LOGE("MyService instantiate"); // defaultServiceManager ()获得ServiceManager的对象引用,addService()可向ServiceManager注册新的服务 int r = defaultServiceManager()->addService(String16("android.myservice"), new MyService()); LOGE("MyService r = %d/n", r); return r; } MyService::MyService() { LOGV("MyService created"); mNextConnId = 1; pthread_key_create(&sigbuskey, NULL); } MyService::~MyService() { pthread_key_delete(sigbuskey); LOGV("MyService destroyed"); } // 每个系统服务都继承自BBinder类,都应重写BBinder的onTransact虚函数。当用户发送请求到达Service时,系统框架会调用Service的onTransact函数,该函数分析接收到的数据包,调用相应的接口函数处理请求 status_t MyService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch(code) { case 0: { pid_t pid = data.readInt32(); int num = data.readInt32(); num = num + 100; reply->writeInt32(num); return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); } } }; //namespace (3)编写libservice/Android.mk文件view plain# File: Android.mk LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := myservice.cpp LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) LOCAL_SHARED_LIBRARIES := libutils libbinder LOCAL_MODULE_TAGS := optional LOCAL_PRELINK_MODULE := false LOCAL_MODULE := libmyservice include $(BUILD_SHARED_LIBRARY) (4)编译libmyservice.so动态库在android源码主目录下view plain$ source build/envsetup.sh including device/htc/passion/vendorsetup.sh including device/samsung/crespo4g/vendorsetup.sh including device/samsung/crespo/vendorsetup.sh $ mmm frameworks/base/myservice/libmyservice/ 编译成功后生成文件:out/target/product/generic/system/lib/libmyservice.so3.2 myserver代码实现(1)新建目录myservice/myserver,并进入该目录(2)编写myserver/myserver.cpp文件view plain#include <sys/types.h> #include <unistd.h> #include <grp.h> #include <binder/IPCThreadState.h> #include <binder/ProcessState.h> #include <binder/IServiceManager.h> #include <utils/Log.h> #include <private/android_filesystem_config.h> #include "../libmyservice/myservice.h" using namespace android; int main(int argc, char** argv) { sp<ProcessState> proc(ProcessState::self()); sp<IServiceManager> sm = defaultServiceManager();//获得ServiceManager接口 LOGI("ServiceManager: %p", sm.get()); MyService::instantiate(); //执行addService()函数,注册服务 ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); //进入循环,等待客户端的请求 return 0; } (3)编写myserver/Android.mk文件view plain# File: Android.mk LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= myserver.cpp LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) LOCAL_SHARED_LIBRARIES := libutils libbinder libmyservice LOCAL_MODULE_TAGS := optional LOCAL_PRELINK_MODULE := false LOCAL_MODULE := myserver include $(BUILD_EXECUTABLE) (4)编译myserver可执行程序在android源码主目录下执行:view plain$mmm frameworks/base/myservice/myserver/ 编译成功后生成文件:out/target/product/generic/symbols/system/bin/myserver3.3 MyClient客户端代码实现(1)新建目录myservice/myclient,进入该目录(2)编写myclient/myclient.h文件view plainnamespace android { class MyClient { public: void add100(int n); private: static const void getMyService(); //通过ServiceManager获取服务接口 }; }; //namespace (3)编写myclient/myclient.cpp文件view plain#include <binder/IServiceManager.h> #include <binder/IPCThreadState.h> #include "myclient.h" namespace android { sp<IBinder> binder; void MyClient::add100(int n) { getMyService(); Parcel data, reply; int answer; data.writeInt32(getpid()); data.writeInt32(n); LOGE("BpMyService::create remote()->transact()/n"); binder->transact(0, data, &reply); answer = reply.readInt32(); printf("answner=%d/n", answer); return; } const void MyClient::getMyService() { sp<IServiceManager> sm = defaultServiceManager(); binder = sm->getService(String16("android.myservice")); LOGE("MyClient::getMyService %p/n",sm.get()); if (binder == 0) { LOGW("MyService not published, waiting..."); return; } } }; //namespace using namespace android; int main(int argc, char** argv) { MyClient* p = new MyClient(); p->add100(1); return 0; } (4)编写myclient/Android.mk文件view plainLOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= myclient.cpp LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) LOCAL_SHARED_LIBRARIES := libutils libbinder libmyservice LOCAL_MODULE_TAGS := optional LOCAL_PRELINK_MODULE := false LOCAL_MODULE := myclient include $(BUILD_EXECUTABLE) (5)编译myclient可执行程序在android源码主目录下,执行:view plain$ mmm frameworks/base/myservice/myclient/ 编译成功后生成可执行文件:out/target/product/generic/symbols/system/bin/myclient3.4在模拟器上运行(1)启动模拟器view plain$ cd ~/software/android/android-sdk-linux/tools $ ./emulator -avd gbread -partition-size 512 (2)拷贝libmyservice.so到模拟器的/system/lib目录view plain$cd out/target/product/generic/obj/lib $adb remount $ adb push libmyservice.so /system/lib 159 KB/s (10084 bytes in 0.061s) (3)拷贝myserver到模拟器的/system/bin目录view plain$cd out/target/product/generic/symbols/system/bin $ adb push myserver /system/bin 668 KB/s (27508 bytes in 0.040s) (4)拷贝myclient到/system/bin目录view plain$ adb push myclient /system/bin 1549 KB/s (46840 bytes in 0.029s) (5)在模拟器上启动服务,并执行客户端程序。view plain# adb shell # cd system/bin # ls my* myclient myserver # ./myserver # ./myclient answner=101/n# 由客户端程序的执行结果可知,由服务端返回的执行结果是正确的。

如何在Android下使用Binder

实现一个binder通信实例,需要经过以下步骤:(1)获得ServiceManager的对象引用(2)向ServiceManager注册新的Service(3)在Client中通过ServiceManager获得Service对象引用(3)在Client中发送请求,由Service返回结果。下面看具体的代码如何实现。3.1 libmyservice代码实现(1)新建目录frameworks/base/myservice/libservice,进入该目录view plain$ cd frameworks/base$ mkdir myservice$ cd myservice$ mkdir libmyservice$ cd libmyservice(2)编写libmyservice/myservic.h文件view plain#include <utils/threads.h>#include <utils/RefBase.h>#include <binder/IInterface.h>#include <binder/BpBinder.h>#include <binder/Parcel.h>namespace android {class MyService : public BBinder{mutable Mutex mLock;int32_t mNextConnId;public:static int instantiate();MyService();virtual ~MyService();virtual status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t);};}; //namespace(2)编写libservice/myservice.cpp文件view plain#include "myservice.h"#include <binder/IServiceManager.h>#include <binder/IPCThreadState.h>namespace android {static struct sigaction oldact;static pthread_key_t sigbuskey;int MyService::instantiate(){LOGE("MyService instantiate");// defaultServiceManager ()获得ServiceManager的对象引用,addService()可向ServiceManager注册新的服务int r = defaultServiceManager()->addService(String16("android.myservice"), new MyService());LOGE("MyService r = %d/n", r);return r;}MyService::MyService(){LOGV("MyService created");mNextConnId = 1;pthread_key_create(&sigbuskey, NULL);}MyService::~MyService(){pthread_key_delete(sigbuskey);LOGV("MyService destroyed");}// 每个系统服务都继承自BBinder类,都应重写BBinder的onTransact虚函数。当用户发送请求到达Service时,系统框架会调用Service的onTransact函数,该函数分析接收到的数据包,调用相应的接口函数处理请求status_t MyService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){switch(code){case 0: {pid_t pid = data.readInt32();int num = data.readInt32();num = num + 100;reply->writeInt32(num);return NO_ERROR;}break;default:return BBinder::onTransact(code, data, reply, flags);}}}; //namespace(3)编写libservice/Android.mk文件view plain# File: Android.mkLOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES := myservice.cppLOCAL_C_INCLUDES := $(JNI_H_INCLUDE)LOCAL_SHARED_LIBRARIES := libutils libbinderLOCAL_MODULE_TAGS := optionalLOCAL_PRELINK_MODULE := falseLOCAL_MODULE := libmyserviceinclude $(BUILD_SHARED_LIBRARY)(4)编译libmyservice.so动态库在android源码主目录下view plain$ source build/envsetup.shincluding device/htc/passion/vendorsetup.shincluding device/samsung/crespo4g/vendorsetup.shincluding device/samsung/crespo/vendorsetup.sh$ mmm frameworks/base/myservice/libmyservice/编译成功后生成文件:out/target/product/generic/system/lib/libmyservice.so

android studio导入flutter项目报错:Dart SDK is not configured

在Android studio中导入flutter项目时报错:Dart SDK is not configured,这是因为在android studio里面没有配置Dart SDK的问题,可以通过下面步骤进行配置: 1.打开File =》Setting =》Language & Frameworks => Dart 2.勾选 “enable Dart support for the project”,并且选择Dart SDK path,路径为 D:installandroidflutterincachedart-sdk ,其中D:installandroidflutter是flutter SDK路径 3. 然后点击确定,重新编译即可

android系统修改了app之后启动一直停留在freeing init memory这个地方是什么原因

app是应用吧,修改应用干嘛

Android中提供了3种电话状态,但是好像没有给出电话的接通状态的判断,怎么判断拨打和接听电话是否接通?

来电通里可以看到通话时间

HTC有部手机被网友刷成了可同时运行Windows Mobile 和Android两个系统?是哪部手机?

我记得原来s900可以。不过现在这两个系统可以刷到一起的手机应该不只一款了。

Android系统各版本中文代号

各版本代号对应关系:纸杯蛋糕(Android 1.5)甜甜圈(Android 1.6)松饼(Android 2.0/2.1)冻酸奶(Android 2.2)姜饼(Android 2.3)蜂巢(Android 3.0)冰激凌三明治(Android 4.0)果冻豆(Jelly Bean,Android4.1和Android 4.2)

android中文是什么意思

安卓系统

如何让android自动挂载U盘

设置_开发者选项_打开USB调试

你那个用U盘装android系统是怎么做的。能教一下我吗?

欲先善其事,必先利其器,要想成功的在上网本上安装android系统还是要有不少准备工作的!下面是需要下载的与准备的工具~ 1. 大于1G的优盘一个。2. 到http://code.google.com/p/android-x86/downloads/list下载一个android的安装文件,可以下载名字中带有froyo-x86版本的。这是Android2.2版本适用于x86架构CPU的安装文件。3. 在http://unetbootin.sourceforge.net/网站上下载一个UNetbootin软件,这个软件可以让你轻松的把Linux操作系统装进U盘,这次也要用他来制作U盘启动的!基本上需要准备的就是上面三项了,都准备齐全了,就要开始安装的第一步了!首先,我们要做的是制作一个android系统安装U盘!先在桌面建立一个新文件夹,然后将下载好的android系统文件和UNetbootin软件放进去。之后插入U盘并将其格式化。先将下载好的两个文件放好 打开新建的文件夹,启动UNetbootin软件,直接选择光盘镜像。点击这排最后的三个点,选择文件夹内的android系统文件。之后最下面类型选择USB驱动器,然后选择你的U盘盘符,直接选择光盘镜像,就是之前下载好的android系统文件.iso后缀类型USB驱动器,选择好U盘盘符后直接确定即可安装 完成以上设置后,点击确认然后软件会自动将android系统装入U盘中,完成后点击退出即可。将U盘插入电脑,开机并进入bios(开机时狂按F2或者F8键),并选择U盘HDD优先启动。启动后会进入U盘启动安装界面:1、Live CD-Run Android without installation 直接运行android系统 2、Live CD-VESA mode 普通视频显示模式 3、Live CD-Debug mode 调试模式 4、Installation – install Android to harddisk 将android安装到硬盘上 可以先选则Live CD-Run Android without installation直接在U盘上运行android系统,看看电脑是否支持该系统。省的直接安装好不能用的话,卸载比较麻烦!而且您要是只是想体验下的话,这时候直接进入系统就OK了!不过这样U盘运行的话,系统不太稳定,而且无法保存设置。如果您想将android装到电脑硬盘中打造双系统的话,就选Installation – install Android to harddisk,将系统直接安装到硬盘中。选择安装硬盘,不用format了,直接OKyes继续安装安装成功了 运行android吧! OK!到这里整个android系统就已经成功的安装到您硬盘中了!相当的容易,只需要一路回车就行了!android系统启动画面很快,也就3-5秒就闪进去了。待机画面,要用鼠标解锁才能进入桌面。待机画面桌面的图标一样可以拖动到这里整个双系统打造已经彻底完成,同时安装两款系统启动并不冲突,但并不能随时切换需要从新启动电脑才行。从开机速度和待机时间上来说对于windows系统还是有一定优势的。软件方面有一个很大的问题,android的很多软件都需要调动通讯模块,因此对于上网本来说这是个难题!存储卡方面插入SD卡没有反映,但是插入U盘的话到是可以显示成功插入SD卡。相信在更新的android x86版本中会对这些问题都有所改进的,到时候就算得上是一个完美的操作系统了!

android怎么依赖cardview

最好是汉化版的.那样比较易懂.此软件打开之后.在屏幕上点击最长的选项条.安装EXT/.........手机会重启.之后再打开此软件.有一个Froyo工具.点进去.再点第一个.先扫描全部.然后勾选全部-OK.全部转移到 xxxxSD或者ft32/16的.点下就OK了.Froyo工具里第二个选项就是设置你默认安装的存储位置了.点进去之后.点SD或者Fat16/32的选项.大部分都是选定第二项.点OK 就可以了

Android有多强大??

Android 用甜点作为它们系统版本的代号的命名方法开始于 Andoird 1.5 发布的时候。 作为每个版本代表的甜点的尺寸越变越大,然后按照26个字母数序:纸杯蛋糕,甜甜圈,松饼,冻酸奶,姜饼,蜂巢。 Android 1.1 发布时间:发布于 2008 年9月 Android 1.5 Cupcake纸杯蛋糕   发布时间:发布于 2009 年 4 月 Android 1.6 Donut甜甜圈   发布时间:2009 年 9 月 Android 2.0 Eclair松饼   发布时间:2009 年 10 月 26 日 Android 2.1 Eclair松饼   发布时间: 2009 年 10 月 26 日   Android 2.1主要特性:提升硬件速度   更多屏幕以及分辨率选择   大幅度的用户界面改良支持   Exchange活动墙纸   大幅改进虚拟键盘   蓝牙 2.1   Google 地图 Android 2.2 Froyo冻酸奶   谷歌于北京时间2010年5月20日晚上10:30点在旧金山Moscone会展中心举办Google I/O 2010大会第二天的会议,Google正式发布了代号是“froyo 冻酸奶”的Android操作系统2.2版。   相对于上一版本的 改变:   1、整体性能大幅度的提升   2、3G网络共享功能。   3、Flash的支持。   4、App2sd功能。   5、全新的软件商店。   6、更多的Web应用API接口的开发。 Android 2.2 For x86 在几位华人软件工程师的努力下,中国的用户已经可以享受到真正在上网本上可以安装使用的Android了,这就是孙翊、黄志伟和Corentin Chary和其他几位活跃的开发人员正在参与的Android-x86开源项目。 此外,还有其他的开发人员如Kelly2.Blue、Wu Hai Gang、Swand ke 和 Wallace1 wang,他们都是来自中国大陆和台湾的华人软件工程师。   在孙翊发来的最新版本更新说明中,明确表示:他们已经解决了众多的技术难题,包括中文拼音输入法的bug修订,蓝牙支持,无线网卡支持、SSL的bug修订等,甚至已经可以直接安装到上网本上,从硬盘启动。 Android2.3 Gingerbread姜饼   北京时间2010年12月7日凌晨,Google正式对外发布了他们的下一代智能手机操作系统Android 2.3也就被大家所熟知的Android Gingerbread系统。   主要更新包括:   游戏:增加了新的垃圾回收和优化处理事件,以提高对游戏的支持能力。 原生代码可直接存取输入和感应器事件、EGL/OpenGL ES、OpenSL ES。 新的管理窗口和生命周期的框架。   多媒体:支持VP8和WebM视频格式,提供AAC和AMR宽频编码,提供了新的音频效果器,比如混响、均衡、虚拟耳机和低频提升   通讯方式:支持前置摄像头、SIP/VOIP和NFC(近场通讯)   站在用户的角度看,这次更新的亮点主要有:   简化界面、速度提升:   更快更直观的文字输入:   一键文字选择和复制/粘帖:   改进的电源管理系统:   新的应用管理方式:   原生支持前置摄像头、互联网通话和NFC(近场通讯):   系统原生支持VoIP,可以在联系人里加入它的SIP帐户,然后直接通过系统来拨打VoIP电话。   增加下载管理器: Android 2.4 Ice cream sandwich冰激凌三明治    预计在2011年第四季度发布。 其甜品代号为 Ice cream sandwich(冰激凌三明治)   目前已知的Android 2.4带来的更新包括更多的动画特效、更快的运行速度、软件通话降噪、视频聊天等。 Android N.n 有可靠的消息人士表示,继“冰激凌三明治”之后,下一版Android系统的代号将为“Jelly Bean”。 Android3.0 Honeyb(蜂巢)   3.0系统特性   ·优化针对平板   ·全新设计的UI增强网页浏览功能   ·n-app purchases功能 Android3.1 Honeyb 蜂巢(改进3.0BUG)   ·经过优化的Gmail电子邮箱;   ·全面支持GoogleMaps   Android 3.1Honeyb(3.0改进)   将Android手机系统跟平板系统再次合并,从而方便开发者。   任务管理器可以滚动,支持USB 输入设备(键盘、鼠标等)。   支持 Google TV.可以支持XBOX 360无线手柄   widget支持的变化,能更加容易的定制屏幕widget插件。 Android 3.2 Honeyb(蜂巢)   2011年7月13日,谷歌公司放出了新版“蜂巢”Android 3.2的升级源码,合作厂商摩托罗拉亦在当日发布了针对旗下XOOM平板电脑的升级固件,为用户更新新版系统。   Android 3.2这一新版平板电脑操作系统开始支持7英寸设备,并引入了应用显示缩放功能,可以让那些针对手机开发的应用,更平滑的显示在平板电脑上。 编辑本段系统优势 开放性   在优势方面,Android平台首先就是其开放性,开放的平台允许任何移动终端厂商加入到Android联盟中来。 显著的开放性可以使其拥有更多的开发者,随着用户和应用的日益丰富,一个崭新的平台也将很快走向成熟。   挣脱束缚   在过去很长的一段时间,特别是在欧美地区,手机应用往往受到运营商制约,使用什么功能接入什么网络,几乎都受到运营商的控制。 自从iPhone上市,用户可以更加方便地连接网络,运营商的制约减少。 随着EDGE、HSDPA这些2G至3G移动网络的逐步过渡和提升,手机随意接入网络已不是运营商口中的笑谈。   丰富的硬件   这一点还是与Android平台的开放性相关,由于Android的开放性,众多的厂商会推出千奇百怪,功能特色各具的多种产品。   开发商   Android平台提供给第三方开发商一个十分宽泛、自由的环境。 因此不会受到各种条条框框的阻挠,可想而知,会有多少新颖别致的软件会诞生。 但也有其两面性,血腥、暴力、 *** 方面的程序和游戏如何控制正是留给Android难题之一。   Google应用   从搜索巨人到全面的互联网渗透,Google服务如地图、邮件、搜索等已经成为连接用户和互联网的重要纽带,而Android平台手机将无缝结合这些优秀的Google服务。 编辑本段系统缺陷 一、Android系统手机泄密   二、拨号后自动挂断电话 通话BUG频繁出现    三、对硬件配置要求高 制造成本增加    四、系统费电严重 安卓手机续航不足    五、系统计算器计算有偏差    例如在Android系统自带的计算器内输入14.52-14.49,正确结果应该是0.03,但是计算器结果显示的数字为0.0299999。 编辑本段研发联盟 开放手机联盟 为了推广Android,Google和几十个手机相关企业建立了开放手机联盟(Open Handset Alliance)。 联盟成员包括摩托罗拉(Motorola)、HTC、SAMSUNG、LG、Intel、NVIDIA、SiRF、Skype、KUPA Map 、MTK 以及中国移动在内的34家技术和无线应用的领军企业。 这34家企业中并不包含把持Symbian的Nokia公司,以及凭借着iPhone风光正在的Apple公司,微软没有加入,加拿大RIM和它的Blackberry也被挡在门外。   手机开放联盟大家庭成员名单:   终端制造商   Motorola(摩托罗拉)- 美国(美国最大的手机制造商,著名老牌IT公司)   Sony Ericsson(索尼爱立信)- 英国(索尼和爱立信的合资公司)   HTC(宏达国际电子股份有限公司)-中国台湾   Samsung Electronics(三星电子)- 韩国   LG Electronics(LG电子)- 韩国   Lumigon (丹麦陆力更手机公司)- 丹麦   ARCHOS(爱可视)- 法国   TOSHIBA(东芝)- 日本 安卓 SHARP(夏普)-日本   Fujitsu(富士通)-日本   NEC(日本电気株式会社)-日本   魅族 - 中国   小米--中国   移动运营商   China Tele(中国电信)- 中国   China Mobile(中国移动)- 中国   China Uni(中国联通)- 中国   SK Tele - 韩国   KT - 韩国   LG U - 韩国   KDDI by AU - 日本   Softbank -日本   NTT DoCoMo(日本电信电话公司)- 日本   Sprint Nextel(美国斯普林特Nextel公司)- 美国   Tele Italia(意大利电信)- 意大利   Telefónica - 西班牙   T-Mobile - 德国   半导体公司   ARM- 英国   Texas Instruments(德州仪器)- 美国   Qualm(高通)- 美国   NVIDIA(英伟达)- 美国   MediaTek(联发科)- 中国台湾   ST(意法半导体)- 欧洲   Infineon(英飞凌科技)- 德国   ST-Ericsson(ST爱立信)- 欧洲   Audience (听众)- 美国   Broad (博通)- 美国   Intel(英特尔)- 美国   Marvell (俊茂微电子)- 美国   SiRF(瑟夫)- 美国   Synaptics(新思)- 美国   HP(惠普)- 美国   软件公司    Aplix - 日本   Ascender - 美国   Skype(微软)- 美国   E *** ertec(微迅)- 瑞士   Living Image - 美国   NMS munications - 加拿大   Noser Engineering AG - 德国   Nuance munication - 美国   PacketVideo - 美国   SkyPop - 美国   Sonix Network - 美国   The Astonishing Tribe - 瑞典   Wind River Systems(风河)- 美国 编辑本段使用品牌 大事记 2008年9月22日,美国运营商德国T-Mobile在纽约正式发布第一款Android手机——T-Mobile G1。 该款手机为台湾宏达电子(HTC)代工制造,是世界上第一部使用Android操作系统的手机,支持WCDMA/HSPA网络,理论下载速率7.2Mbps,并支持Wi-Fi。   2009年10月28日正式发布了Android 2.0 智能手机操作系统。   2010年1月索尼爱立信首款Android机型X10上市 。   2010年1月7日,Google在其美国总部正式向外界发布了旗下首款合作品牌手机Nexus One(HTC G5),并同时开始对外发售。   2010年7月9日,美国NDP集团调查显示,Android系统已占据了美国移动系统市场28%的份额。   北京时间2011年3月25日,据国外媒体报道,谷歌周四表示,谷歌暂停开源Android3.0,并将暂时阻止小型手机生产商使用其Android 3.0“Honeyb”系统,期限未定。   谷歌一位发言人通过电子邮件声明称,Honeyb是专为平板电脑而非手机设计的,在该系统以开源形式发布前,还有很多工作要做。 谷歌向《商业周刊》表示,推迟发布可能达数月之久。 国内品牌 HTC 安卓手机(5张)  魅族   魅族M9为一款多点触摸手机,于2010年12月16日发布,2011年1月1日正式上市。   J.wong在论坛发帖确定魅族M9将不能刷原生的Android系统,M9将不是简简单单的在Android系统上加个UI,而是深层定制安卓系统,现有的Android软件的兼容性也绝对不是问题。 J.wong甚至表态想刷Android系统的安卓控们请远离M9。 J.wong表示魅族M9的系统虽然内核采用Android内核,但从UI和用户体验方面完全看不出任何安卓的影子,使用Android内核只是为了能兼容数以十万计的安卓软件,增强魅族M9的软件扩展性,让M8之前一直被诟病的软件数量成为历史。   天语   天语W700是K-Touch天语手机在2011年初推出的一款WCDMA制式3G Android智能手机,同时,它还是第一款国产双核手机。 这款采用了NVIDIA TEGRA2平台的高端智能手机首次发布在位于拉斯维加斯的CES2011展会上亮相。   天语W700采用基于ARM Cortex-A9 Dual Core的Tegra2 AP20H处理器,主频为1GHz,具有高性能低功耗的特点,它集成了高清视频处理器、图像处理器、音频处理器等众多模块的高度整合处理器。      联想   OMS和T-mobile G1搭载的Android(以最初上市版本为主)的不同之处就是可以使用户自行关闭正在运行的程序而不是由系统控制:按住屏幕上方向下拖动即可看到任务管理器。   HKC Pearl   做为目前在市面上唯一正式销售的Windows和Android系统双系统手机,这款HKC Pearl 珍珠珠配备了QVGA屏幕,内存采用了128MB/256MB的标准配置,主处理器采用PXA 310处理器,624Mhz的主频性能非常强劲,而且机器还配备了Wi-Fi,蓝牙2.0无线传输设置。   华为   华为U8230在外观上有别于其他Android手机的塑料风格,通体的银灰色和正面功能键盘的发丝纹路都洋溢着商务机型的味道。 而作为功能上的特色,U8230拥有一块3.5英寸的大屏幕、高达1500毫安时的锂电池和一枚320万象素摄像头采用Android平台1.5版本。   中兴   中兴最近也大力发展android手机,推出了v880。   海尔   海尔的产品也青睐搭载android系统。 海尔于09年上市的H7采用直板全触屏设计,操作系统上正是采用了最新的Google Android2.0操作系统。   海尔于2011年7月亮相青岛国际消费电子博览会的haipad,搭载创新工场家族“点心os”首款为PAD定制的“点心—互联网智能手持终端解决方案”。   华禹   xPhone是由上海禹华通信技术有限公司设计的,采用类iphone的触控设计,配置了3寸WQVGA分辨率的触摸屏,内建300W像素的摄像头,搭载Android平台,采用主频 624Mhz的Marvell PXA-310处理器,拥有128MB SDRAM+256MB ROM的内存配置,支持最大16GB的存储卡扩展,给出的参数中还加入了WiFi功能。   琦基   去年11月27日,琦基发布了全球首款Google Android/Windows Mobile双操作系统的智能手机琦基i6,采用Google Android操作系统的叫做琦基i6 goal,采用Windows Mobile操作系统的叫做琦基i6 Win。   蓝魔   蓝魔的V系列MP4以及平板电脑采用安卓系统。   酷派   推出D539等多款搭载Android平台的3G商务机型   小米   小米手机是小米公司(全称北京小米科技有限责任公司)研发的一款高性能发烧级智能手机。 手机预计2011年8月发布,售价1999元,主要针对手机发烧友,采用线上销售模式。 小米手机使用了高通Snapdragon S3 MSM8260手机处理器,也是世界上首款双核1.5GHz的智能手机。 国外品牌 三星、LG、摩托罗拉、夏普、索尼爱立信 编辑本段系统架构 应用程序 Android以Java为编程语言,从接口到功能,都有层出不穷的变化,其中Activity等同于J2ME的MIDlet,一个 Activity 类(class)负责创建视窗(window),一个活动中的Activity就是在 foreground(前景)模式,背景运行的程序叫做Service。 两者之间通过由ServiceConnection和AIDL连结,达到复数程序同时运行的效果。 如果运行中的 Activity 全部画面被其他 Activity 取代时,该 Activity 便被停止(stopped),甚至被系统清除(kill)。   View等同于J2ME的Displayable,程序人员可以通过 View 类与“XML layout”档将UI放置在视窗上,Android 1.5的版本可以利用 View 打造出所谓的 Widgets,其实Widget只是View的一种,所以可以使用xml来设计layout,HTC的Android Hero手机即含有大量的widget。 至于ViewGroup 是各种layout 的基础抽象类(abstract class),ViewGroup之内还可以有ViewGroup。 View的构造函数不需要再Activity中调用,但是Displayable的是必须的,在Activity 中,要通过findViewById来从XML 中取得View,Android的View类的显示很大程度上是从XML中读取的。 View 与事件(event)息息相关,两者之间通过Listener 结合在一起,每一个View都可以注册一个event listener,例如:当View要处理用户触碰(touch)的事件时,就要向Android框架注册View.OnClickListener。 另外还有Image等同于J2ME的BitMap。 中介软件 操作系统与应用程序的沟通桥梁,应用分为两层:函数层(Library)和虚拟机(Virtual Machine)。 Bionic是 Android 改良libc的版本。 Android 同时包含了Webkit,所谓的Webkit 就是Apple Safari 浏览器背后的引擎。 Surface flinger 是就2D或3D的内容显示到屏幕上。 Android使用工具链(Toolchain)为Google自制的Bionic Libc。   Android采用OpenCORE作为基础多媒体框架。 OpenCORE可分7大块:PVPlayer、PVAuthor、Codec、PacketVideo Multimedia Framework(PVMF)、Operating System patibility Library(OSCL)、mon、OpenMAX。   Android 使用skia 为核心图形引擎,搭配OpenGL/ES。 skia与Linux Cairo功能相当,但相较于Linux Cairo, skia 功能还只是雏形的。 2005年Skia公司被Google收购,2007年初,Skia GL源码被公开,目前Skia 也是Google Chrome 的图形引擎。   Android的多媒体数据库采用SQLite数据库系统。 数据库又分为共用数据库及私用数据库。 用户可通过ContentResolver类(Column)取得共用数据库。   Android的中间层多以Java 实现,并且采用特殊的Dalvik 虚拟机(Dalvik Virtual Machine)。 Dalvik虚拟机是一种“暂存器型态”(Register Based)的Java虚拟机,变量皆存放于暂存器中,虚拟机的指令相对减少。   Dalvik虚拟机可以有多个实例(instance), 每个Android应用程序都用一个自属的Dalvik虚拟机来运行,让系统在运行程序时可达到优化。 Dalvik 虚拟机并非运行Java字节码(Bytecode),而是运行一种称为.dex格式的文件。 硬件抽像层 Android 的 HAL(硬件抽像层)是能以封闭源码形式提供硬件驱动模块。 HAL 的目的是为了把 Android framework 与 Linux kernel 隔开,让 Android 不至过度依赖 Linux kernel,以达成 kernel independent 的概念,也让 Android framework 的开发能在不考量驱动程序实现的前提下进行发展。   HAL stub 是一种代理人(proxy)的概念,stub 是以 *.so 档的形式存在。 Stub 向 HAL“提供”操作函数(operations),并由 Android runtime 向 HAL 取得 stub 的 operations,再 callback 这些操作函数。 HAL 里包含了许多的 stub(代理人)。 Runtime 只要说明“类型”,即 module ID,就可以取得操作函数。 编程语言 Android 是运行于 Linux kernel之上,但并不是GNU/Linux。 因为在一般GNU/Linux 里支持的功能,Android 大都没有支持,包括Cairo、X11、Alsa、FFmpeg、GTK、Pango及Glibc等都被移除掉了。 Android又以bionic 取代Glibc、以Skia 取代Cairo、再以opencore 取代FFmpeg 等等。 Android 为了达到商业应用,必须移除被GNU GPL授权证所约束的部份,例如Android将驱动程序移到 userspace,使得Linux driver 与 Linux kernel彻底分开。 bionic/libc/kernel/ 并非标准的kernel header files。 Android 的 kernel header 是利用工具由 Linux kernel header 所产生的,这样做是为了保留常数、数据结构与宏。   目前Android 的 Linux kernel控制包括安全(Security),存储器管理(Memory Management),程序管理(Process Management),网络堆栈(Network Stack),驱动程序模型(Driver Model)等。 下载Android源码之前,先要安装其构建工具 Repo来初始化源码。 Repo 是 Android 用来辅助Git工作的一个工具。 安全与权限 Android本身是一个权限分立的操作系统。 在这类操作系统中,每个应用都以唯一的一个系统识别身份运行(Linux用户ID与群组ID)。 系统的各部分也分别使用各自独立的识别方式。 Linux就是这样将应用与应用,应用与系统隔离开。   系统更多的安全功能通过权限机制提供。 权限可以限制某个特定进程的特定操作,也可以限制每个URI权限对特定数据段的访问。   Android安全架构的核心设计思想是,在默认设置下,所有应用都没有权限对其他应用、系统或用户进行较大影响的操作。 这其中包括读写用户隐私数据(联系人或电子邮件),读写其他应用文件,访问网络或阻止设备待机等。   安装应用时,在检查程序签名提及的权限,且经过用户确认后,软件包安装器会给予应用权限。 从用户角度看,一款Android应用通常会要求如下的权限:   拨打电话、发送短信或彩信、修改/删除SD卡上的内容、读取联系人信息、读取日程信息,写入日程数据、读取电话状态或识别码、精确的(基于GPS)地理位置、模糊的(基于网络获取)地理位置、创建蓝牙连接、对互联网的完全访问、查看网络状态,查看WiFi状态、避免手机待机、修改系统全局设置、读取同步设定、开机自启动、重启其他应用、终止运行中的应用、设定偏好应用、震动控制、拍摄图片等。   一款应用应该根据自身提供的功能,要求合理的权限。 用户也可以分析一款应用所需权限,从而简单判定这款应用是否安全。 如一款应用是不带广告的单机版,也没有任何附加内容需要下载,那么它要求访问网络的权限就比较可疑。

Android 系统各版本的推出年份是多少(如Android1.0 1.5 2.1 2.2)

  系统版本  Android 1.1  android手机  发布时间:发布于 2009 年 2 月 代表手机:T-MOBILE G1  Android 1.5 Cupcake  发布于 2009 年 5 月 代表手机:摩托罗拉CILQ  Android 1.6 Donut  2009 年 9 月发布 代表手机:索尼爱立信 X10,摩托罗拉A1680  Android 2.0 Eclair  2009 年 10 月 26 日 代表机型:摩托罗拉XT800,摩托罗拉里程碑  Android 2.1 Eclair  Android 2.1: 2009 年 10 月 26 日,又一个主要版本升级以创纪录的速度放出。这次,大版本升级到了Android 2.1 “Eclair.” Android 2.1主要特性: 提升硬件速度 更多屏幕以及分辨率选择 大幅度的用户界面改良 支持 Exchange活动墙纸 大幅改进虚拟键盘 蓝牙 2.1 Google 地图 Android 2.0.1 SDK 于 2009 年 12 月 3 日 发布,之后是2010 年 1 月 10 日的 2.1 版本。很多用户和围观群众可能会奇怪:“为什么 Android 会用甜点作为它们系统版本的代号?”,这个命名方法开始于 Andoird 1.5 发布的时候。作为每个版本代表的甜点的尺寸越变越大,然后按照字母数序:小蛋糕,甜甜圈还有松饼。之前人们预计 2.2 版本的代号会是“馅饼”,但这个被最终证明是错误的,“FroYo”(冻酸奶)才是 Android 2.2 这个伴随 Google Nexus One 发布的新版的最新代号。  Android 2.2 Froyo  谷歌于北京时间2010年5月20日晚上10:30点在旧金山Moscone会展中心举办Google I/O 2010大会第二天的会议,Google正式发布了代号是“froyo 冻酸奶”的Android操作系统2.2版。 相对于上一版本的 改变: 1、整体性能大幅度的提升 2、3G网络共享功能。 3、Flash的支持。 4、App2sd功能。 5、全新的软件商店。 6、更多的Web应用API接口的开发。  Android 2.3 Gingerbread  gingerdroid  北京时间2010年12月7日凌晨,Google正式对外发布了他们的下一代智能手机操作系统Android 2.3也就被大家所熟知的Android Gingerbread系统。 主要更新包括: 游戏:增加了新的垃圾回收和优化处理事件,以提高对游戏的支持能力。原生代码可直接存取输入和感应器事件、EGL/OpenGL ES、OpenSL ES。新的管理窗口和生命周期的框架。 多媒体:支持VP8和WebM视频格式,提供AAC和AMR宽频编码,提供了新的音频效果器,比如混响、均衡、虚拟耳机和低频提升 通讯方式:支持前置摄像头、SIP/VOIP和NFC(近场通讯) 站在用户的角度看,这次更新的亮点主要有: 简化界面、速度提升: 更快更直观的文字输入: 一键文字选择和复制/粘帖: 改进的电源管理系统: 新的应用管理方式: 原生支持前置前置摄像头、互联网通话和NFC(近场通讯): 系统原生支持VoIP,可以在联系人里加入它的SIP帐户,然后直接通过系统来拨打VoIP电话。 增加下载管理器:  Android 2.4 Gingerbread  就像Android 2.0和2.1版本都使用Eclair(法式奶油夹心甜点)一样,Android 2.3和2.4将会共享Gingerbread(姜饼)代号。这两个版本之间的变化不会太大,但是会有不少功能更新。 目前已知的Android 2.4带来的更新包括更多的动画特效、更快的运行速度、软件通话降噪、视频聊天等。 Android 2.4系统不会是之前一直谣传的Android 3.0,其真正的版本号将会是Android 2.4。  Android 3.0 Honeycomb  2011年2月3日凌晨,谷歌正式发布了专用于平板电脑的Android 3.0 Honeycomb系统。这是首个基于Android的平板电脑专用操作。首款采用Android3.0系统的是MOTO XOOM 。该机是摩托罗拉移动在2011年1月5日,在美国拉斯维加斯 CES电子消费展推出的旗下首款平板电脑。 3.0系统特性 ·专用于平板电脑 ·全新设计的UI增强网页浏览功能 ·n-app purchases功能 ·经过优化的Gmail电子邮箱; ·全面支持Google Maps

android手机系统是那国的

美国的。给您个安卓系统发展史:2003年10月,Andy Rubin等人创建Android公司,并组建Android团队。2005年8月17日,Google低调收购了成立仅22个月的高科技企业Android及其团队。安迪鲁宾成为Google公司工程部副总裁,继续负责Android项目。2007年11月5日,谷歌公司正式向外界展示了这款名为Android的操作系统,并且在这天谷歌宣布建立一个全球性的联盟组织,该组织由34家手机制造商、软件开发商、电信运营商以及芯片制造商共同组成,并与与84家硬件制造商、软件开发商及电信营运商组成开放手持设备联盟(Open Handset Alliance)来共同研发改良Android系统,这一联盟将支持谷歌发布的手机操作系统以及应用软件,Google以Apache免费开源许可证的授权方式,发布了Android的源代码。2008年,在GoogleI/O大会上,谷歌提出了Android HAL架构图,在同年8月18号,Android获得了美国联邦通信委员会(FCC)的批准,在2008年9月,谷歌正式发布了Android 1.0系统,这也是Android系统最早的版本。2009年4月,谷歌正式推出了Android 1.5这款手机,从Android 1.5版本开始,谷歌开始将Android的版本以甜品的名字命名,Android 1.5命名为Cupcake(纸杯蛋糕)。该系统与Android 1.0相比有了很大的改进。2009年9月份,谷歌发布了Android 1.6的正式版,并且推出了搭载Android 1.6正式版的手机HTC Hero(G3),凭借着出色的外观设计以及全新的Android 1.6操作系统,HTC Hero(G3)成为当时全球最受欢迎的手机。Android 1.6也有一个有趣的甜品名称,它被成为Donut(甜甜圈)。2010年2月份,Linux内核开发者Greg Kroah-Hartman将Android的驱动程序从Linux内核“状态树”(“staging tree”)上除去,从此,Android与Linux开发主流将分道扬镳。在同年5月份,谷歌正式发布了Android 2.2操作系统。谷歌将Android 2.2操作系统命名为Froyo,翻译完名为冻酸奶。2010年10月份,谷歌宣布Android系统达到了第一个里程碑,即电子市场上获得官方数字认证的Android应用数量已经达到了10万个,Android系统的应用增长非常迅速。在2010年12月,谷歌正式发布了Android 2.3操作系统Gingerbread (姜饼)。2011年1月,谷歌称每日的Android设备新用户数量达到了30万部,到2011年7月,这个数字增长到55万部,而Android系统设备的用户总数达到了1.35亿,Android系统已经成为智能手机领域占有量最高的系统。2011年8月2日,Android手机已占据全球智能机市场48%的份额,并在亚太地区市场占据统治地位,终结了Symbian(塞班系统)的霸主地位,跃居全球第一。2011年9月份,Android系统的应用数目已经达到了48万,而在智能手机市场,Android系统的占有率已经达到了43%。继续在排在移动操作系统首位。在本月19号,谷歌将会发布全新的Android 4.0操作系统,这款系统被谷歌命名为Ice Cream Sandwich(冰激凌三明治)。 2012年1月6日,谷歌Android Market目前已有10万开发者推出超过40万活跃的应用,大多数的应用程序为免费。Android Market应用程序商店目录在新年首周周末突破40万基准,距离突破30万应用仅4个月。在2011年早些时候,Android Market从20万增加到30万应用也花了四个月。

android os v2.2和2.1的区别

2.2可以安装Flash插件,支持在线视频播放

android操作系统是哪个国家的

这个的话,它这个是属于谷歌系统开发出来的呀。

android历史_android历史记录列表展示

Android一词的本义指“机器人”,同时也是Google于2007年11月5日宣布的基于Linux平台的开源手机操作系统的名称,该平台由操作系统、中间件、用户界面和应用软件组成。其发展历史如下:2003年10月,AndyRubin等人创建Android公司,并组建Android团队。2005年8月17日,Google低调收购了成立仅22个月的高科技企业Android及其团队。安迪鲁宾成为Google公司工程部副总裁,继续负责Android项目。2007年11月5日,谷歌公司正式向外界展示了这款名为Android的操作系统,并且在这天谷歌宣布建立一个全球性的联盟组织,发布了Android的源代码。2008年,在GoogleI/O大会上,谷歌提出了AndroidHAL架构图,在同年8月18号,Android获得了美国联邦通信委员会(FCC)的批准,在2008年9月,谷歌正式发布了Android1.0系统,这也是Android系统最早的版本。2009年4月,谷歌正式推出了Android1.5这款手机,从Android1.5版本开始,谷歌开始将Android的版本以甜品的名字命名,Android1.5命名为Cupcake(纸杯蛋糕)。该系统与Android1.0相比有了很大的改进。2009年9月份,谷歌发布了Android1.6的正式版,并且推出了搭载Android1.6正式版的手机HTCHero(G3),凭借着出色的外观设计以及全新的Android1.6操作系统,HTCHero(G3)成为当时全球最受欢迎的手机。Android1.6也有一个有趣的甜品名称,它被称为Donut(甜甜圈)。2010年2月份,Linux内核开发者GregKroah-Hartman将Android的驱动程序从Linux内核“状态树”(“stagingtree”)上除去,从此,Android与Linux开发主流将分道扬镳。在同年5月份,谷歌正式发布了Android2.2操作系统。谷歌将Android2.2操作系统命名为Froyo,翻译完名为冻酸奶。2010年10月份,谷歌宣布Android系统达到了第一个里程碑,即电子市场上获得官方数字认证的Android应用数量已经达到了10万个,Android系统的应用增长非常迅速。在2010年12月,谷歌正式发布了Android2.3操作系统Gingerbread(姜饼)。2011年1月,谷歌称每日的Android设备新用户数量达到了30万部,到2011年7月,这个数字增长到55万部,而Android系统设备的用户总数达到了1.35亿,Android系统已经成为智能手机领域占有量最高的系统。2011年8月2日,Android手机已占据全球智能机市场48%的份额,并在亚太地区市场占据统治地位,终结了Symbian(塞班系统)的霸主地位,跃居全球第一。2011年9月份,Android系统的应用数目已经达到了48万,而在智能手机市场,Android系统的占有率已经达到了43%。继续在排在移动操作系统首位。谷歌将会发布全新的Android4.0操作系统,这款系统被谷歌命名为IceCreamSandwich(冰激凌三明治)。2013年11月1日,Android4.4正式发布,从具体功能上讲,Android4.4提供了各种实用小功能,新的Android系统更智能,添加更多的Emoji表情图案,UI的改进也更现代,如全新的HelloiOS7半透明效果。

Android是那个国家的系统?

美国的。给您个安卓系统发展史:2003年10月,Andy Rubin等人创建Android公司,并组建Android团队。2005年8月17日,Google低调收购了成立仅22个月的高科技企业Android及其团队。安迪鲁宾成为Google公司工程部副总裁,继续负责Android项目。2007年11月5日,谷歌公司正式向外界展示了这款名为Android的操作系统,并且在这天谷歌宣布建立一个全球性的联盟组织,该组织由34家手机制造商、软件开发商、电信运营商以及芯片制造商共同组成,并与与84家硬件制造商、软件开发商及电信营运商组成开放手持设备联盟(Open Handset Alliance)来共同研发改良Android系统,这一联盟将支持谷歌发布的手机操作系统以及应用软件,Google以Apache免费开源许可证的授权方式,发布了Android的源代码。2008年,在GoogleI/O大会上,谷歌提出了Android HAL架构图,在同年8月18号,Android获得了美国联邦通信委员会(FCC)的批准,在2008年9月,谷歌正式发布了Android 1.0系统,这也是Android系统最早的版本。2009年4月,谷歌正式推出了Android 1.5这款手机,从Android 1.5版本开始,谷歌开始将Android的版本以甜品的名字命名,Android 1.5命名为Cupcake(纸杯蛋糕)。该系统与Android 1.0相比有了很大的改进。2009年9月份,谷歌发布了Android 1.6的正式版,并且推出了搭载Android 1.6正式版的手机HTC Hero(G3),凭借着出色的外观设计以及全新的Android 1.6操作系统,HTC Hero(G3)成为当时全球最受欢迎的手机。Android 1.6也有一个有趣的甜品名称,它被成为Donut(甜甜圈)。2010年2月份,Linux内核开发者Greg Kroah-Hartman将Android的驱动程序从Linux内核“状态树”(“staging tree”)上除去,从此,Android与Linux开发主流将分道扬镳。在同年5月份,谷歌正式发布了Android 2.2操作系统。谷歌将Android 2.2操作系统命名为Froyo,翻译完名为冻酸奶。2010年10月份,谷歌宣布Android系统达到了第一个里程碑,即电子市场上获得官方数字认证的Android应用数量已经达到了10万个,Android系统的应用增长非常迅速。在2010年12月,谷歌正式发布了Android 2.3操作系统Gingerbread (姜饼)。2011年1月,谷歌称每日的Android设备新用户数量达到了30万部,到2011年7月,这个数字增长到55万部,而Android系统设备的用户总数达到了1.35亿,Android系统已经成为智能手机领域占有量最高的系统。2011年8月2日,Android手机已占据全球智能机市场48%的份额,并在亚太地区市场占据统治地位,终结了Symbian(塞班系统)的霸主地位,跃居全球第一。2011年9月份,Android系统的应用数目已经达到了48万,而在智能手机市场,Android系统的占有率已经达到了43%。继续在排在移动操作系统首位。在本月19号,谷歌将会发布全新的Android 4.0操作系统,这款系统被谷歌命名为Ice Cream Sandwich(冰激凌三明治)。 2012年1月6日,谷歌Android Market目前已有10万开发者推出超过40万活跃的应用,大多数的应用程序为免费。Android Market应用程序商店目录在新年首周周末突破40万基准,距离突破30万应用仅4个月。在2011年早些时候,Android Market从20万增加到30万应用也花了四个月。

Android OS的版本记录

下面图表提供了Android平台及设备访问Google Play的相关数据(2015-01-05)。 版本 代号名 更新日 API层阶 发行率 4.4kitkat 2013年10月311939.1%4.3.xJelly Bean2013年7月24186.5%4.2.xJelly Bean2012年9月131720.3%4.1.xJelly Bean2012年6月91619.2%4.0.3-4.0.4Ice Cream Sandwich2011年12月16156.7%2.3.3-2.3.7Gingerbread2011年2月9107.8%2.2Froyo2010年5月2080.4%Android移动操作系统的历史始于2007年11月发布的Android测试版。第一个商业版本的Android1.0,发布于2008年9月。 Android是由谷歌和开发手机联盟(OHA)的不断发展下,已经出现了大量的更新其基本操作系统,因为它原始的发行。这些更新通常修复bug并增加新的功能。自2009年4月以来,Android版本已经下开发一个代号,按字母顺序排列:蛋糕,甜甜圈,巧克力慕斯蛋糕,升级Froyo,姜饼,蜂窝,冰淇淋三明治,和果冻豆发布。截至2013年,超过500万的活跃设备使用的是Android OS全球的主要版本果冻豆4.2,发布于2012年11月商用设备。 android商用版(2007-2008)Android alpha有至少两个内部发布谷歌和开放手机联盟的Android测试版发布于2007年11月。其临时的命名方案中,虚构的机器人的名字命名其代号,各种版本的代号为“Astro Boy”,“Bender”和“R2-D2”MorrilDan(丹·莫里尔)创作了一些吉祥物标志。2009年4月,采用了Android1.5蛋糕甜点命名方案,已为广大公众发布。Android公测版2007年9月5号 android测试版 发布,开发套件(SDK)发布于2007年11月12日。 因此2007年9月5号就是Android的第一个“生日”。公开测试版本的SDK发布以下顺序: 2007年11月16日:M3-rc22a 2007年12月14日:M3-rc37a 2008年2月13日:M5-RC1 2008年3月3日:M5-RC 2008年8月18日:0.9 2008年:9月23日1.0-R1 API级别的版本历史Android1.0(API级别1)Android1.0的第一个商业版软件,2008年9月23日搭载 第一款Android设备HTC Dream, 纳入以下的Android1.0功能Android 1.1(API级别2)2009年2月9日,被释放的Android 1.1更新,最初只为HTC Dream的。Android 1.1的被称为“佩蒂特四国”内部,虽然没有正式使用这个名字。 更新解决的bug,改变了Android的API,并添加了一些功能; Android1.5蛋糕(API3级)2009年4月27日,发布的Android 1.5更新,基于Linux内核2.6.27。 这是第一个版本正式使用基于一个代号上甜点项(“蛋糕”),一个主题将用于今后所有版本。更新包括一些新功能和UI修订: Android 1.6(API级别4)2009年9月15日,发布了Android 1.6 SDK- 被称为甜甜圈 - 基于Linux内核2.6.29。 在更新包括了许多新的功能:Android 2.0(API级别5)于2009年10月26日,Android 2.0的SDK- 代号为“巧克力蛋糕” - 发布,基于Linux内核2.6.29 的变化包括: Android 2.0.1(API级别6)Android 2.1(API7级别)升级Froyo的Android 2.2-2.2.3(API8级)2010年5月20日,为Android 2.2(升级Froyo,冷冻酸奶)的SDK发布,基于Linux内核2.6.32。 Android 2.3-2.3.2姜饼(API级别9)2010年12月6日,在Android 2.3(姜饼)的SDK发布,基于Linux内核2.6.35。[46] [47]的变化包括: Android 2.3.3-2.3.7姜饼(API10级)Android 3.0蜂窝(API11级)2011年2月22日,发布的Android 3.0(蜂窝)SDK- 唯一的Android更新 -基于Linux内核2.6.36。 这个版本的第一个设备摩托罗拉Xoom平板电脑,于2011年2月24日搭载运行。 更新的功能包括:Android 3.1蜂窝(API12级)Android 3.2蜂窝的(API13级)大多数第一代和第二代谷歌电视功能的设备使用蜂窝3.2。Android 4.0-4.0.2冰淇淋三明治(API14级)SDK为Android 4.0.1(冰淇淋三明治),基于Linux内核3.0.1, 于2011年10月19日公开发布。]谷歌的工作人员指出,Android 4.0的“在理论上与任何Android兼容” 2.3.x的生产设备, 为Android 4.0的源代码 更新引入了许多新功能,包括: Android 4.0.3-4.0.4冰淇淋三明治(API15级)终止Adobe系统的Flash播放器支持。 Anroid 4.1(API16级)谷歌宣布了Android 4.1(果冻豆)2012年6月27日在谷歌I / O大会。基于Linux内核3.0.31,糖豆是一个渐进的更新与完善的功能和性能的用户界面。涉及性能的改善,它采用触摸预期,三重缓冲,扩展VSYNC计时和固定为60 fps的帧速率创建一个流体和“界面顺滑”的用户界面。 2012年7月9日Android 4.1果冻豆发布Android开源项目,另外Nexus 7平板电脑是第一台设备运行糖豆。 Android4.2果冻豆(API17级)谷歌预计在2012年10月29日发生在纽约市宣布果冻豆4.2,但该事件被取消,因为飓风桑迪。 而不是重新安排的现场活动中,谷歌宣布新版本,“新口味的果冻豆”。设备运行Android4.2 LG的Nexus4和三星的Nexus10于2012年11月13日公布。 Android5.0酸橙派 预计2013年10月发布。

Android系统各版本中文代号是什么?

从Android1.5版本开始,谷歌开始将Android的版本以甜品的名字命名AndroidBeta--阿童木Android1.0--发条机器人Android1.5--Cupcake(纸杯蛋糕)Android1.6--Donut(甜甜圈)Android2.0/2.1--Eclair(松饼)Android2.2--Froyo(冻酸奶)Android2.3--Gingerbread(姜饼)Android3.0--Honeycomb(蜂巢)Android4.0--IceCreamSandwich(冰激凌三明治)Android4.1--JellyBean(果冻豆)
 首页 上一页  16 17 18 19 20 21 22 23 24 25 26  下一页  尾页