asfman
android developer
posts - 90,  comments - 213,  trackbacks - 0

http://zerodoo.appspot.com/android.1.0001.html
1
开发相关

1.1 横/竖屏处理

1.1.1 程序启动时处理横/竖屏及如何禁止横/竖屏变化

摘自:http://cenphoenix.javaeye.com/blog/463937

AndroidManifest.xml 里面加入这一行

android :screenOrientation="landscape "

其中: landscape 是横向, portrait 是纵向。

不过android中每次屏幕的切换动会重启Activity,所以应该在Activity销毁前保存当前活动的状态,在Activity再次Create的时候载入配置。在activity加上

android:configChanges="keyboardHidden|orientation"

属性,就不会重启activity.而是去调用 onConfigurationChanged(Configuration newConfig) .这样就可以在这个方法里调整显示方式.

Java代码:

@Override
public void onConfigurationChanged(Configuration newConfig) {
try {
super.onConfigurationChanged(newConfig);
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
// land
        } else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
// port
        }
} catch (Exception ex) {
}
}

1.1.2 程序运行时处理横/竖屏变化

当屏幕变为横屏的时候,系统会重新呼叫当前Activity的OnCreate方法,你可以把以下方法放在你的OnCreate中来检查当前的方向,然后可以让你的 SetContentView来载入不同的Layout xml.

if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
Log.i("info", "landscape");
} else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
Log.i("info", "portrait");
}

关于屏幕切换的时候,首先需要在androidmanifest.xml中加入配置

android:configChanges="orientation|keyboardHidden|navigation"

这样在程序中. Activity就不会重复的调用onCreate(),甚至不会调用 onPause.onResume ,只会调用一个 onConfigurationChanged(Configuration newConfig) ,这是在XML加入配置选项的前提下。

如果在就加入选项的前提下.如上所说. Activity会重新激活onCreate方法,根据你自己的需求来选择配置改变时的处理机制这样比较好一点。

1.1.3 模拟器处理横/竖屏

CTRL+F12CTRL+F11 可以切换模拟器的横/竖屏。

eclipse 里面 run dialog->target 里面可以设置。如果是命令行可以使用参数

emulator -skin HVGA-L

1.2 分析android动画模块

1.2.1 主要思路

Tween 动画通过对 View 的内容完成一系列的图形变换 (包括平移、缩放、旋转、改变透明度)来实现动画效果。

具体来讲,预先定义一组指令,这些指令指定了图形变换的类型、触发时间、持续时间。这些指令可以是以 XML 文件方式定义,也可以是以源代码方式定义。程序沿着时间线执行这些指令就可以实现动画效果。

动画的进度使用 Interpolator 控制,android 提供了几个 Interpolator 子类,实现了不同的速度曲线,如LinearInterpolator 实现了匀速效果、 Accelerateinterpolator 实现了加速效果、DecelerateInterpolator 实现了减速效果等。还可以定义自己的 Interpolator 子类,实现抛物线、自由落体等物理效果。

动画的运行模式有两种:

  • 独占模式,即程序主线程进入一个循环,根据动画指令不断刷新屏幕,直到动画结束;
  • 中断模式,即有单独一个线程对时间计数,每隔一定的时间向主线程发通知,主线程接到通知后更新屏幕;

图形变换通过仿射矩阵实现。图形变换是图形学中的基本知识。简单来说就是,每种变换都是一次矩阵运算。在 Android 中,Canvas 类中包含当前矩阵,当调用 Canvas.drawBitmap (bmp, x, y, Paint) 绘制时,android 会先把 bmp 做一次矩阵运算,然后将运算的结果显示在 Canvas 上。这样,编程人员只需不断修改 Canvas 的矩阵并刷新屏幕,View 里的对象就会不停的做图形变换,动画就形成了。

在 android 中提供了 Animation 、 Interpolator、Transformation 等类具体实现 Tween 动画,下面逐一分析。

1.2.2 Animation 类及其子类

Animation 类及其子类是动画的核心模块,它实现了各种动画效果,如平移、缩放、旋转、改变透明度等。

Tween 动画的每一桢都根据 Interpolator 对 view 的内容做一次图形变换,因此 Animation 的核心工作是做变换(transformation)。

Aniamtion 是基类,他记录了动画的通用属性和方法。主要的属性包括动画持续时间、重复次数、interpolator 等。动画里最重要的方法是 getTransformation (currentTime, outTransformation),该方法根据当前间 (currentTime) 和 interpolator,计算当前的变换,在 outTransformation 中返回。

TranslateAnimation、RotateAnimation、AlphaAnimation 等是 Animation 的子类,分别实现了平移、旋转、改变 Alpha 值等动画。

每个动画都重载了父类的 applyTransformation 方法,这个方法会被父类的 getTransformation 方法调用。另外每个动画还有个 initialize 方法,完成初始化工作。

不同的动画具有不同的属性,如 RotateAnimation 的属性是起始角度、终止角度和旋转点坐标, TranslateAnimation 的属性是起始位置和终止位置。 AlphaAnimation 的属性是起始 alpha 值和终止 alpha 值。

Animation 类及其子类的类图如下所示:

attachments/Animation类及其子类的类图.png

1.2.3 Interpolator 类及其子类

Interpolator 定义了动画的变化速度,可以实现匀速、正加速、负加速、无规则变加速等;

Interpolator 是基类,封装了所有 Interpolator 的共同方法,它只有一个方法,即 getInterpolation (float input),该方法 maps a point on the timeline to a multiplier to be applied to the transformations of an animation.

LinearInerpolator、 AccelerateInterpolator, DecelerateInterpolator, AccelerateDecelerateInterpolator,CycleInterpolator 是 Interpolator 的子类,分别实现了匀速、加速、减速、变速、循环等效果。

对于 LinearInterpolator ,变化率是个常数,即 f (x) = x.

public float getInterpolation(float input) {
return input;
}
public float getInterpolation(float input) {
return input;
}

对于 AccelerateInterpolator,开始变化很慢,然后逐渐变快,即 f(x) = x*x 或者 f(x) = pow(x, 2*mFactor).

public float getInterpolation(float input) {
if (mFactor == 1.0f) {
return (float)(input * input);
} else {
return (float)Math.pow(input, 2 * mFactor);
}
}
public float getInterpolation(float input) {
if (mFactor == 1.0f) {
return (float)(input * input);
} else {
return (float)Math.pow(input, 2 * mFactor);
}
}

对于 AccelerateDecelerateInterpolator,变化率开始和结束都很慢,但中间很快,即 f(x) = (cos ((x+1)*PI) / 2.0f) + 0.5f.

public float getInterpolation(float input) {
return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
}
public float getInterpolation(float input) {
return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
}

Interpolator 类及其子类的类图如下所示:

attachments/Interpolator类及其子类的类图.png

1.2.4 Transformation 类

Transformation 记录了仿射矩阵 Matrix,动画每触发一次,会对原来的矩阵做一次运算, View 的 Bitmap 与这个矩阵相乘就可实现相应的操作(旋转、平移、缩放等)。

Transformation 类封装了矩阵和 alpha 值,它有两个重要的成员,一是 mMatrix,二是 mAlpha。

Transformation 类图如下所示:

attachments/Transformation类图.png

1.2.5 如何在 View 中实现动画

从逻辑上讲,实现动画需要如下几步:

  1. view 创建动画对象,设置动画属性,调用 invalidate 刷新屏幕,启动动画;
  2. invalidate 方法触发了 onDraw 函数;
  3. 在 onDraw 函数中:
    • 调用动画的 getTransformation 方法,得到当前时间点的矩阵
    • 将该矩阵设置成 Canvas 的当前矩阵
    • 调用 canvas 的 drawBitmap 方法,绘制屏幕。
    • 判断 getTransformation 的返回值,若为真,调用 invalidate 方法,刷新屏幕进入下一桢;若为假,说明动画完成。

整个流程可用一个序列图表示:

attachments/在View中实现动画序列图.png

1.2.6 使用样例

下面的代码是一个 view,系统创建 view 时会调用 onCreate 方法,该方法定义了一个 TranslateAniamtion,指定了移动起点和终点,动画持续时间为 1s,最后调用 startAnimation 将该动画保存在 View 的成员 mCurrentAnianmtion 中并启动动画。

注意,在 View 中需要定义成员变量 mCurrentAnimation 和 mTransformation ,分别记录当前的动画和变换。另外需要定义成员函数 startAnimation 启动动画。

class MyView extends View {
Animation mCurrentAnimation  = null;
Transformation mTransformation = new Transformation;
private void setAnimation(Animation animation) {
mCurrentAnimation = animation;
if (animation != null) {
animation.reset();
}
}
public void startAnimation(Animation animation) {
animation.setStartTime(animation.START_ON_FIRST_FRAME);
setAnimation(animation);
invalidate();
}
void onDraw (Canvas canvas) {
long curTime = SystemClock.uptimeMillis ();
if (mCurrentAniamtion == null){
canvas.drawBitmap (b, x, y, mPaint);
} else {
if (!mCurrentAnimation.isInitialized())  //initialize animation
                mCurrentAnimation.initialize (w, h, pw, ph);
boolean more = mCurrentAnimation.getTransformation (curTime, mTransformation);
if(more) {
Matrix m = canvas.getMatrix();
canvas.setMatrix (mTransformation.getMatrix());
canvas.drawBitmap (b, x, y, mPaint);
canvas.setMatrix (m);
this.invalidate ();
} else {
mCurrentAnimation = null;
this.invalidate ();
}
}
}
void onCreate (){
Animation anim = new TranslateAnimation (10, 20, 0, 0);
anim.setDuration (1000); // 1s
        anim.setInterpolator (new AcceleratInterpolator(3.0f));
startAniamtion (anim);
}
}

2 教你在谷歌Android平台中处理图片

摘自:http://tech.it168.com/a2008/0805/199/000000199568.shtml

【IT168 专稿】Android是谷歌推出的业界首个完全开放且免费的移动应用开发平台,自从去年11月份谷歌宣布举办总奖金为 1000万美元的Android开发者大赛以来,人们对了解它、使用它的热情逐渐升温。自开赛以来全世界已经有近1800 个新参赛产品被提交,其中甚至有很多因其独具一格的创意而登上技术界媒体的头条,成为人们关注的焦点。在这个平台上引入了许多有趣的概念,不过很多开发者依然认为它只是一个Linux、 Java和谷歌自己的应用程序编程接口API的组合产物。本文将通过介绍图片处理相关的编程,来让你明白使用Android平台非常简单,而且这个平台也非常强大。

2.1 开始之前的入门知识了解

现在关于Android的参考资料并不是很多,而当前最好的资料则来自于谷歌自己的Android的网站:http://code.google.com/android/。在这儿有你所需要的所 有必须的开发工具、插件和示例代码,你可以免费下载它们。下载操作很容易,在此不再浪费笔墨介绍。

除了在线文档之外,你还可以通过加入社区论坛的方式来得到技术帮助。如果你是初学者,我推荐你选择使用免费的开发工具Eclipse,因为它集成了最好的 Android SDK,另外还有调试软件和模拟器。根据很多有经验的开发者介绍,尽管通过命令行或批处理脚本都可以实现创建Android项目,但是使用Eclipse无疑是最容易上手的方法。

处理图像的API有哪些?

Android的API可以实现很多强大的功能,其中包括:

·SQLite结构化数据存储数据库(SQLite for structured data storage):通过它你不用花很大劲就可以在你的应用程序内嵌入一个微型数据库。 ·图形库支持:基于OpenGL ES嵌入版的最佳二维图形库和三维图形库。 ·集成Web浏览器支持 ·多媒体支持:它支持常用的音频、视频和图像格式。 ·谷歌API:映射(Mapping)功能可以让第三方代码显示和控制一个谷歌地图。它还可以通过XMPP支持一个叫做GTalkService的P2P服务。 ·硬件相关的支持:有很多人们所期待的功能,用来支持GSM电话、蓝牙、3G、WiFi、定位服务等相关硬件。

在谷歌提供的大量API中,我们主要关注下面两个程序包中的相关API:

·android.graphics:核心渲染包,它提供了一些初级图形工具,诸如画布、颜色过滤器、画笔等,可以让你直接在屏幕上进行图像处理。 ·android.graphics.drawable:编译过的可视化资源用来做背景、标题或屏幕的其他部分。

由于图片是位图文件,因此我们将重点了解和使用在android.graphics.Bitmap下的API。

文件I/O和支持的图片格式

Android支持好几种常见的静态图片格式,例如PNG、JPG和GIF。在本文的示例中,我们将使用JPG格式。如果你考虑使用图片的透视功能,可能选择PNG格式更合适一些。

为了从你的软件中查看一个图片文件,你应该将它放在你的软件根目录下的res/drawable目录下。一旦这个图片放在这个文件夹下之后,当你重新编译打包的时候,会自动为它产生一个资源ID。举个例子来说,如果你拥有一个叫做pic1.jpg的图片文件,它将可以通过它的资源ID R.drawable.pic1在程序中被访问。你可以看到这个图像文件扩展名已经被脱去,而R则代表了整体资源文件R.java,它是自动生成的,除非你非常了解这个文件中的资源结构,不推荐你编辑它里面的内容。下面的示例代码介绍如何通过一个图像文件的资源ID来访问它。

1 Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), 2 R.drawable.pic1); 3 int picwidth = mBitmap.width(); 4 int picheight = mBitmap.height();

如果你希望阅读和编写一个没有指定文件夹结构的图片文件,它应该放在模拟器的/data/data/YourPackageName/files/目录下。举个例子来说,如果你为你的例程创建一个程序包名称为com.cyl.TutorialOnImages。那么当你在运行的时候创建一个新的图片文件,它将被放在/data/data/com.cyl.TutorialOnImages/files/文件夹下。请记住每一个Android应用都将以它自己的用户和组ID来启动,因此你专门设定,某些文件夹是不可以通过你的软件来访问的。下面是一段当你希望输出一个位图到一个output.jpg文件时的代码。

1 try { 2 FileOutputStream fos = super.openFileOutput("output.jpg", 便3 MODEWORLDREADABLE); 4 5 mBitmap.compress(CompressFormat.JPEG, 75, fos); 6 7 fos.flush(); 8 fos.close(); 9 } catch (Exception e) { 10 Log.e("MyLog", e.toString()); 11 }

图片查看、颜色和透明

每一个Android应用应该有一个屏幕布局。你可以在软件内动态的创建它,或者通过一个外部XML文件来指定它。这个文件默认是main.xml。为了包含一个图片,你要使用一个叫做ImageView的查看类。下面是main.xml文件的内容:

1 <?xml version="1.0" encoding="utf-8"?> 2 3 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 4 android:orientation="vertical" 5 android:layoutwidth="fillparent" 6 android:layoutheight="fillparent" 7 > 8 9 <ImageView id="@+id/picview" 10 android:layoutwidth="wrapcontent" 11 android:layoutheight="wrapcontent" 12 /> 13 14 </LinearLayout>

如同图片文件可以被通过一个资源ID来访问一样,编译后在全局资源文件R.java中自动为main.xml产生一个叫做R.layout.main的资源ID。下面是当应用程序首次在模拟器上启动时的默认视图。

图1、软件在模拟器上首次启动

每一个图像像素通过一个4字节整数来展现。最高位字节用作alpha通道;换言之用来实现透明/不透明控制。255代表完全不透明;0则代表完全透明。接下来一个字节是red红色通道;255代表完全是红色。依次类推接下来两个字节相应的实现绿色和蓝色通道。

操作图像像素

现在你可以对单独的像素进行处理了。通过使用 android.graphics.Bitmap API中的getPixels,可以加载像素到一个整数数组中。在本文例子中,你将按照一定规则对每一个像素实现着色。经过这个处理后,所有的像素将被转化为一个范围在0到255的字节码。android.graphics.Bitmap API中的setPixels则用来加载这个整数数组到一个图像中。最后一步是通过ImageView变量mIV来更新屏幕。以下是实现这个染色过程的代码片段。

1 private void TintThePicture(int deg) { 2 int[] pix = new int[picw * pich]; 3 mBitmap.getPixels(pix, 0, picw, 0, 0, picw, pich); 4 5 int RY, GY, BY, RYY, GYY, BYY, R, G, B, Y; 6 double angle = (3.14159d * (double)deg) / 180.0d; 7 int S = (int)(256.0d * Math.sin(angle)); 8 int C = (int)(256.0d * Math.cos(angle)); 9 10 for (int y = 0; y < pich; y++) 11 for (int x = 0; x < picw; x++) 12 { 13 int index = y * picw + x; 14 int r = (pix[index] >> 16) & 0xff; 15 int g = (pix[index] >> 8) & 0xff; 16 int b = pix[index] & 0xff; 17 RY = ( 70 * r - 59 * g - 11 * b) / 100; 18 GY = (-30 * r + 41 * g - 11 * b) / 100; 19 BY = (-30 * r - 59 * g + 89 * b) / 100; 20 Y = ( 30 * r + 59 * g + 11 * b) / 100; 21 RYY = (S * BY + C * RY) / 256; 22 BYY = (C * BY - S * RY) / 256; 23 GYY = (-51 * RYY - 19 * BYY) / 100; 24 R = Y + RYY; 25 R = (R < 0) ? 0 : ((R > 255) ? 255 : R); 26 G = Y + GYY; 27 G = (G < 0) ? 0 : ((G > 255) ? 255 : G); 28 B = Y + BYY; 29 B = (B < 0) ? 0 : ((B > 255) ? 255 : B); 30 pix[index] = 0xff000000 | (R << 16) | (G << 8) | B; 31 } 32 33 Bitmap bm = Bitmap.createBitmap(picw, pich, false); 34 bm.setPixels(pix, 0, picw, 0, 0, picw, pich); 35 36 // Put the updated bitmap into the main view 37 mIV.setImageBitmap(bm); 38 mIV.invalidate(); 39 40 mBitmap = bm; 41 pix = null; 42 }

图2:按下中间按钮时的结果

实现用户交互操作

看完上面的内容后,我们已经知道了如何导入和导出一个图像文件,并且为它创建一个视图,进而在这个图片中处理每一个像素。下面我们要了解的一件事情是实现一个简单的用户交互,这样可以根据用户端的输入来实现相应操作。android.view.KeyEvent中的API让你可以处理响应操作。这个软件被设定为等待方向键的中央键的按键事件。当它被按下的时候,它将为这个图片以增加20的方式来进行着色,并将结果保存的一个文件中。

1 public boolean onKeyDown(int keyCode, KeyEvent event) { 2 if (keyCode == KeyEvent.KEYCODEDPADCENTER) { 3 4 // Perform the tinting operation 5 TintThePicture(20); 6 7 // Display a short message on screen 8 nm.notifyWithText(56789, "Picture was tinted", 9 NotificationManager.LENGTHSHORT, null); 10 11 // Save the result 12 SaveThePicture(); 13 14 return (true); 15 } 16 17 return super.onKeyDown(keyCode, event); 18 }

一点建议

·如果处理所有像素要花费比较长的事件,你可能会得到一个应用程序不响应的弹出对话框。这种情况下,你应该创建一个子线程,在它中实现复杂的计算过程。这样可以让主线程实现无中断运行。

·如果这个子线程需要改变主视图(例如对图像进行更新),你应该在主线程中使用一个消息句柄来监听来自子线程的这个消息,并相应的更新视图。一个子线程不能够直接修改主线程中的视图。

·你可以进行某些改进。举个例子来说,它可以被修改类从浏览文件夹或从一个URL中读取图像文件。通过多线程和消息处理可以实现图像动画的处理。

结束语

希望这篇文章能让朋友们对Android平台的工作方式有一个粗略的了解。希望朋友在这个平台上早日创建出自己的应用。

3 用程序改变屏幕垂直或水平(旋屏)

摘自:http://emck.avaw.com/?p=222

android.view.IWindowManager windowService =
android.view.IWindowManager.Stub.asInterface(android.os.ServiceManager.getService("window"));
try {
if (windowService.getOrientation() == 0) {    //Orientation vertical
        windowService.setOrientation(1);  //Orientation horizontal
        Log.i(”info”, “orientation 1 “+windowService.getOrientation());
} else {
Log.i(”info”, “orientation 0 “+windowService.getOrientation());
}
} catch (DeadObjectException e) {
e.printStackTrace();
}

4 Android 技术专题系列

摘自:乡下鱼的博客 email:linuxstb@yahoo.com

4.1 前言

Android是第一个完全开源完全免费的具有商业级产品质量和巨大号召力的Linux 智能手机平台。目前在国内外使用的越来越广泛,相信在不久的将来在国内的山寨机市场上逐步取代MTK的地位。基于个人兴趣,本人怀着好奇心利用业余时间比较系统的研究了这一系统,在这里与大家分享自己的笔记心得。文章记录的可能不是非常系统,有兴趣者欢迎进一步交流。

4.2 Android 是什么

4.2.1 Android 是什么?

Android是一个完整的手机软件平台,包含底层的操作系统(Linux), 中间件以及一些关键应用。 Android 还提供了一个SDK 帮助开发者使用Java语言来开发。

4.2.2 特性

  • 应用框架:提供机制使组件(component)能够被复用和替换
  • Dalvik 虚拟机:为移动设备专门进行优化
  • 浏览器:基于Webkit引擎
  • 优化的图形库:基于一个定制的2D图形库; 3D图形库基于OpenGL ES 1.0草案(硬件加速功能可选)
  • SQLite
  • 媒体支持:包括常见的音频,视频和静态图像格式(MPEG4, H.264, MP3, AAC, AMR, JPG, PNG, GIF)
  • GSM 库(硬件相关)
  • Bluetooth, EDGE, 3G, 和 WIFi (硬件相关)
  • Camera, GPS, compass 和accelerometer (硬件相关)
  • 完善的开发环境, 包括一个模拟器,调试工具,内存和性能分析工具以及Eclipse IDE插件

4.2.3 Android 架构

下图给出了Android平台的主要组成元素(参见 http://code.google.com/android/images/system-architecture.jpg

attachments/android-system-architecture.jpg

4.2.4 应用

Android平台预装了一些核心手机应用,包括电子邮件,短信,日历,地图,浏览器,地址本等等。这些应用都是使用Java语言编写。开发者也需要使用Java语言在Android平台上开发自己的应用程序。

4.2.5 应用框架

核心应用(电子邮件,短信等)所使用的任何API, Android 开发者都可以访问。 Android架构设计的一个重要考虑是使组件(component)易于复用:任意一个应用都可以向系统发布功能,而任意一个其他应用都可以调用这些功能(在不违背系统安全策略前提下)。这个机制还使任意组件(component)都可被开发者替换。

在应用之下是一组服务 (service)和功能库, 包括:

  • 一组丰富和易于扩展的View(控件),用于构建应用的图形用户界面,包括list, grid, 文本框,按钮,甚至一个强大的web浏览器控件
  • Content provider (内容提供者),使一个应用能够访问另外一个应用的数据(如地址本),或者共享自己的数据给其他应用使用。
  • 资源管理器(Resource Manager), 提供接口访问应用的non-code (非代码)资源,如本地化的字符串,图片文件,布局文件等。
  • Notification Manager (通知管理器):所有应用都可以通过Notification Manager在状态栏显示定制化的Alert (通知)或状态信息
  • Activity Manager: 管理应用的生命周期以及activity 窗口的后退机制。

4.2.6

Android平台包含一套C/C++库,供上层的组件使用。开发者不能直接访问这些库,但是可以通过Android应用框架来访问。下面列出了一些核心库:

  • 系统C语言库 - 标准C系统库(libc)的一个BSD-派生实现,并为嵌入式设备进行了优化
  • 媒体库 - 急于PacketVideo的OpenCORE。这个库支持许多音視频格式以及静态图像的播放和录音/像,如MPEG4, H。264, MP3,AAC,AMR, JPG和PNG。
  • Surface Manager - 管理对显示子系统的访问,并无缝的合成多个应用的2D和3D图层
  • LibWebCore - 先进的web浏览器引擎。 Android浏览器应用以及web view (控件,可嵌入其他应用)都是基于这个库。
  • SGL - 底层的2D图形引擎
  • 3D 库 - 基于OpenGL ES 1.0 API的一个实现库。如果硬件提供3D加速功能,这个库会利用硬件这个功能,否则使用一个优化的3D软件库
  • Freetype - 位图和矢量字体引擎
  • SQLite - 轻量级的关系数据库引擎。

4.2.7 Android runtime

Android 包含一套核心库,提供了Java核心库的大多数功能。

每个Android应用运行在自己的进程空间中, 运行在一个单独的Dalvik 虚拟机实例上。Dalvik的设计能够保证同一个设备上有效的运行多个虚拟机(实例)。 Dalvik上运行的可执行文件格式是Dalvik Executable (.dex)。这个格式文件占用较小内存。VM是Register-based (?),运行的类由一个Java 编译器编译生成,然后由"dx"工具转化成.dex格式。

Dalvik虚拟机依赖Linux kernel 提供提供一些基础功能,如线程,初级内存管理等。

4.2.8 Linux Kernel

Android依赖Linux 内核2.6提供的一些核心功能,如安全机制,内存管理,进程管理,网络协议栈和驱动模型等。内核还为硬件提供一个抽象层。

4.3 telephony

Android源码中,hardware/ril目录中包含着Android的telephony源码。这个目录下包含着三个子目录,下面是对三个子目录的具体分析。

4.3.1 一、目录hardware/ril/include分析:

只有一个头文件ril.h包含在此目录下。ril.h中定义了76个如下类型的宏: RILREQUESTXXX ,这些宏代表着客户进程可以向Android telephony发送的命令,包括SIM卡相关的功能,打电话,发短信,网络信号查询等。好像没有操作地址本的功能?

4.3.2 二、目录hardware/ril/libril分析。

本目录下代码负责与客户进程进行交互。在接收客户进程命令后,调用相应函数进行处理,然后将命令响应结果传回客户进程。在收到来自网络端的事件后,也传给客户进程。

  • 文件rilcommands.h:列出了telephony可以接收的命令;每个命令对应的处理函数;以及命令响应的处理函数。
  • 文件rilunsolcommands.h:列出了telephony可以接收的事件类型;对每个事件的处理函数;以及WAKE Type???
  • 文件rilevent.h/cpp:处理与事件源(端口,modem等)相关的功能。rileventloop监视所有注册的事件源,当某事件源有数据到来时,相应事件源的回调函数被触发(firePending -> ev->func())
  • 文件ril.cpp:

RILregister函数: 打开监听端口,接收来自客户进程的命令请求(sfdListen = androidgetcontrolsocket(SOCKETNAMERIL);),当与某客户进程连接建立时,调用listenCallback函数;创建一单独线程监视并处理所有事件源(通过rileventloop)

listenCallback函数: 当与客户进程连接建立时,此函数被调用。此函数接着调用processCommandsCallback处理来自客户进程的命令请求

processCommandsCallback函数: 具体处理来自客户进程的命令请求。对每一个命令,rilcommands.h中都规定了对应的命令处理函数(dispatchXXX), processCommandsCallback会调用这个命令处理函数进行处理。

dispatch系列函数: 此函数接收来自客户进程的命令己相应参数,并调用 onRequest进行处理。

RILonUnsolicitedResponse函数: 将来自网络端的事件封装(通过调用 responseXXX)后传给客户进程。

RILonRequestComplete函数: 将命令的最终响应结构封装(通过调用 responseXXX)后传给客户进程。

response系列函数: 对每一个命令,都规定了一个对应的response函数来处理命令的最终响应;对每一个网络端的事件,也规定了一个对应的 response函数来处理此事件。response函数可被onUnsolicitedResponse或者onRequestComplete 调用。

4.3.3 三、目录hardware/ril/reference-ril分析。

本目录下代码主要负责与modem进行交互。

  • 文件reference-ril.c:此文件核心是两个函数:onRequest和onUnsolicited

onRequest 函数: 在这个函数里,对每一个RILREQUESTXXX请求,都转化成相 应的AT command,发送给modem,然后睡眠等待。当收到此AT command的最终响应后,线程被唤醒,将响应传给客户进程(RILonRequestComplete -> sendResponse)。

onUnsolicited函数: 这个函数处理modem从网络端收到的各种事件,如网络信号变化,拨入的电话,收到短信等。然后将时间传给客户进程(RILonUnsolicitedResponse -> sendResponse)

  • 文件atchannel.c:负责向modem读写数据。其中,写数据(主要是AT command)功能运行在主线程中,读数据功能运行在一个单独的读线程中。

函数atsendcommandfullnolock: 运行在主线程里面。将一个AT command命令写入modem后进入睡眠状态(使用 pthreadcondwait或类似函数),直到 modem读线程将其唤醒。唤醒后此函数获得了AT command的最终响应并返回。

函数readerLoop运行在一个单独的读线程里面,负责从modem中读取数据。读到的数据可分为三种类型:网络端传入的事件;modem对当前AT command的部分响应;modem对当前AT command的全部响应。对第三种类型的数据(AT command的全部响应),读线程唤醒(pthreadcondsignal)睡眠状态的主线程。

4.4 十八-- 媒体文件管理

摘自:http://blog.sina.com.cn/s/blog5e71b14f0100d26g.html

本文引用了 http://letsgoustc.spaces.live.com/Blog/cns!89AD27DFB5E249BA!473.entry 部分内容,特此申明。

Android平台上的媒体文件管理和桌面系统不同。在桌面系统上,不同目录下的媒体文件呈树状结构显示给用户,用户需要进入不同目录寻找该目录下的文件。而在Android平台上,不同目录下的媒体文件则以一层列表方式显示给用户,用户不需进入子目录就可以列出(某种类型的)所有媒体文件。

在Android上,为了实现这种模式的媒体文件管理,对所有管理的媒体文件抽取其元数据(mp3文件包含的元数据可参考http://en.wikipedia.org/wiki/ID3),存储在数据库中,并作为一个content provider提供给其他应用使用。用户的每一次显示媒体文件的操作,就是对这个数据库的一次查询操作。

实现这一功能的代码位于

frameworks/base/core/java/android/provider/MediaStore.java
packages/providers/MediaProvider/src/com/android/providers/media.
frameworks/base/media/java/android/media/MediaScanner*
frameworks/base/media/jni/android_media_*
external/opencore/android/mediascanner.cpp

下面略作分析:

external/opencore/android/mediascanner.cpp负责从媒体文件(mp3, mp4, wma等)中提取元数据。

5 判断两线段是否相交

摘自:http://230996.blog.chinajavaworld.com/entry/4804/0/

public boolean isIntersect(double px1,double py1,double px2,double py2,double px3,double py3,double px4,double py4)//p1-p2 is or not intersect with p3-p4
{
boolean flag = false;
double d = (px2-px1)*(py4-py3) - (py2-py1)*(px4-px3);
if(d!=0)
{
double r = ((py1-py3)*(px4-px3)-(px1-px3)*(py4-py3))/d;
double s = ((py1-py3)*(px2-px1)-(px1-px3)*(py2-py1))/d;
if((r>=0) && (r <= 1) && (s >=0) && (s<=1))
{
flag = true;
}
}
return flag;
}

摘自: http://hi.baidu.com/pyjhytdrdtygk/blog/item/8ee73ad97be61ae338012f48.html

//第一条直线
double x1 = 10, y1 = 20, x2 = 100, y2 = 200;
double a = (y1 - y2) / (x1 - x2);
double b = (x1 * y2 - x2 * y1) / (x1 - x2);
System.out.println("求出该直线方程为: y=" + a + "x + " + b);
//第二条
double x3 = 50, y3 = 20, x4 = 20, y4 = 100;
double c = (y3 - y4) / (x3 - x4);
double d = (x3 * y4 - x4 * y3) / (x3 - x4);
System.out.println("求出该直线方程为: y=" + c + "x + " + d);
double x = ((x1 - x2) * (x3 * y4 - x4 * y3) - (x3 - x4) * (x1 * y2 - x2 * y1))
/ ((x3 - x4) * (y1 - y2) - (x1 - x2) * (y3 - y4));
double y = ((y1 - y2) * (x3 * y4 - x4 * y3) - (x1 * y2 - x2 * y1) * (y3 - y4))
/ ((y1 - y2) * (x3 - x4) - (x1 - x2) * (y3 - y4));
System.out.println("他们的交点为: (" + x + "," + y + ")");

6 获取屏幕尺寸的代码段

摘自:http://www.cnblogs.com/qwhg/articles/1509393.html

public static String getDisplayMetrics(Context cx) {
String str = "";
DisplayMetrics dm = new DisplayMetrics();
dm = cx.getApplicationContext().getResources().getDisplayMetrics();
int screenWidth = dm.widthPixels;
int screenHeight = dm.heightPixels;
float density = dm.density;
float xdpi = dm.xdpi;
float ydpi = dm.ydpi;
str += "The absolute width:" + String.valueOf(screenWidth) + "pixels\n";
str += "The absolute heightin:" + String.valueOf(screenHeight)
+ "pixels\n";
str += "The logical density of the display.:" + String.valueOf(density)
+ "\n";
str += "X dimension :" + String.valueOf(xdpi) + "pixels per inch\n";
str += "Y dimension :" + String.valueOf(ydpi) + "pixels per inch\n";
return str;
}
posted on 2011-04-09 02:45 汪杰 阅读(572) 评论(0)  编辑 收藏 引用 所属分类: Java
只有注册用户登录后才能发表评论。

<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

常用链接

留言簿(15)

随笔分类(1)

随笔档案(90)

文章分类(727)

文章档案(712)

相册

收藏夹

http://blog.csdn.net/prodigynonsense

友情链接

最新随笔

搜索

  •  

积分与排名

  • 积分 - 467490
  • 排名 - 6

最新随笔

最新评论

阅读排行榜

评论排行榜