常用链接

统计

最新评论

#

(转)UML中类图实例

接口:空心圆+直线(唐老鸭类实现了‘讲人话’);
依赖:虚线+箭头(动物和空气的关系);
关联:实线+箭头(企鹅需要知道气候才迁移);
聚合:空心四边形+实线+箭头(雁群和大雁的关系);
合成/组合:实心四边形+实线+箭头(鸟和翅膀的关系);
泛化/
继承:空心三角形+实线(动物和鸟的继承关系);
实现:空心三角形+虚线(实现大雁飞翔的接口);
UML类图  
解释
UML类图:
1.       首先看“动物”矩形框,它代表一个类。该类图分为三层,第一层显示类的名称,如果是抽象类就要用斜体显示。第二层是类的特性,通常就是字段和属性。第三层是类的操作,通常是方法和行为。
   注意前面的符号,‘+’表示public, ‘ 表示private, ‘#’表示protected.   
                                           
2.       飞翔矩形框表示一个接口图,它与类图的区别主要是顶端有《interface》显示,第一行是接口名称,第二行是接口方法。接口还有另一种表示方法,俗称棒棒糖表示法,就是唐老鸭类实现了“讲人话”的接口。
              
interface IFly                              interface Ilanguage                              
{                                              {
   
void Fly();                                    void Speak();
}                                             }

3.       动物,鸟,鸭,唐老鸭他们之间都是继承的关系,继承关系用空心三角形+实现来表示   
                 

4.“大雁”实现了“飞翔”接口。实现接口用空心三角形+虚线来表示。(注:下面的图中应为空心三角形

class Bird:Animal                      class WideGoose:IFly
{                                        {
   
//继承动物类                                 //实现飞翔接口
}                                        }

5.       企鹅与气候有很大的关系,企鹅需要“知道”气候的变化,需要“了解”气候规律。当一个类“知道”另一个类时,可以用关联(association)关系。关联关系用实线箭头来表示  
     
class Penguin :Bird
{
   
private Climate climate;//在企鹅Penguin中,引用到气候Climate对象
}

6.       “大雁”和“雁群”这两个类。大雁是群居动物,每只大雁都属于一个雁群,一个雁群可以有多只大雁。所以它们之间就满足聚合(Aggregation)关系。聚合表示一种弱的“拥有”关系,体现的是A对象可以包含B对象,但B对象不是A对象的一部分。聚合关系用空心的菱形+ 实线箭头表示
    

class WideGooseAggregate
{
   
private WideGoose[] arrayWideGoose;
   
//在雁群WideGooseAggregate类中,有大雁数组对象arrayWideGoose
}

7.       “鸟”和“翅膀”这两个类。鸟和翅膀似整体和部分的关系,并且翅膀和鸟的生命周期是相同的,在这里鸟和其翅膀就是合成关系。合成(composition)是一种强的“拥有”关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样合成关系用实心的的菱形+实线箭头来表示。另外,合成关系的连线两端还有一个数字“1”和数字“2”,,这被称为基数。表明这一端的类可以有几个实例,很显然,一个鸟应该有两支翅膀。如果一个类可能有无数个实例,则就用“n”来表示。关联关系,聚合关系也可以有基数的。
class Bird 
{
  
private Wing wing;
  
public Bird()
   {
      wing
=new Wing();
    
//在鸟Bird类中,初始化时,实例化翅膀Wing,它们之间同时生成
   }
}

8.       “动物”、“氧气”与“水”之间。动物有几大特征,比如有新陈代谢,能繁殖。而动物要有生命,需要氧气,水以及食物等。也就是说动物依赖于氧气和水。它们之间是依赖关系(Dependency),用虚线箭头来表示

abstract class Animal
{
   
public bolism(Oxygen oxygen,Water water)
    {
    } 
}

posted @ 2011-02-12 13:02 九宝 阅读(346) | 评论 (0)编辑 收藏

android register mimetype

在manifest文件里->activity 添加

<intent-filter>

     <action android:name="android.intent.action.VIEW" />

     <category android:name="android.intent.category.DEFAULT" />

     <data android:mimeType="*/*">

</intent-filter>

这样就把当前程序注册为 可以打开/查看所有类型的文件. 或者要查看jpeg, mimeType要改为: image/jpeg

当在文件管理器里点击任何文件, 系统都会试图去执行你的程序.

posted @ 2011-02-11 14:49 九宝 阅读(614) | 评论 (0)编辑 收藏

Android Log Analysis

转自 http://chaozhong84.spaces.live.com/blog/cns!FC149E9A3FC0182B!297.trak

【Android】【转】Android Log Analysis

---------------------------------------------------

本文原创,转载请注明出处,如有错误之处欢迎指出

---------------------------------------------------

Get Log from Android System

adb bugreport > bugreport.txt

copy bugreport to the current directory.

bugreport里面包含了各种log信息,大部分log也可以通过直接运行相关的程序来直接获得.

步骤如下:

1.adb shell 2.进入相关工具程式的目录 3.执行相关程式 4.得到相关信息

下面以输出进程信息为例 1.adb shell 2.输入ps -P 3.可以看到相关进程信息

Log Archive Analysis

1.bugreport

bugreport记录android启动过程的log,以及启动后的系统状态,包括进程列表,内存信息,VM信息等等到.

2.bugreport结构分析

(1)dumpstate

MEMORY INFO

获取该log:读取文件/proc/meminfo

系统内存使用状态

CPU INFO

获取该log:执行/system/bin/top -n 1 -d 1 -m 30 -t

系统CPU使用状态

PROCRANK

获取该log:执行/system/bin/procrank

执行/system/xbin/procrank后输出的结果,查看一些内存使用状态

VIRTUAL MEMORY STATS

获取该log:读取文件/proc/vmstat

虚拟内存分配情况

vmalloc申请的内存则位于vmalloc_start~vmalloc_end之间,与物理地址没有简单的转换关系,虽然在逻辑上它们也是连续的,但是在物理上它们不要求连续。

VMALLOC INFO

获取该log:读取文件/proc/vmallocinfo

虚拟内存分配情况

SLAB INFO

获取该log:读取文件/proc/slabinfo

SLAB是一种内存分配器.这里输出该分配器的一些信息

ZONEINFO

获取该log:读取文件/proc/zoneinfo

zone info

SYSTEM LOG(需要着重分析)

获取该log:执行/system/bin/logcat -v time -d *:v

会输出在程序中输出的Log,用于分析系统的当前状态

VM TRACES

获取该log:读取文件/data/anr/traces.txt

因为每个程序都是在各自的VM中运行的,这个Log是现实各自VM的一些traces

EVENT LOG TAGS

获取该log:读取文件/etc/event-log-tags

EVENT LOG

获取该log:执行/system/bin/logcat -b events -v time -d *:v

输出一些Event的log

RADIO LOG

获取该log:执行/system/bin/logcat -b radio -v time -d *:v

显示一些无线设备的链接状态,如GSM,PHONE,STK(Satellite Tool Kit)...

NETWORK STATE

获取该log:执行/system/bin/netcfg (得到网络链接状态)

获取该log:读取文件/proc/net/route (得到路由状态)

显示网络链接和路由

SYSTEM PROPERTIES

获取该log:参考代码实现

显示一些系统属性,如Version,Services,network...

KERNEL LOG

获取该log:执行/system/bin/dmesg

显示Android内核输出的Log

KERNEL WAKELOCKS

获取该log:读取文件/proc/wakelocks

内核对一些程式和服务唤醒和休眠的一些记录

KERNEL CPUFREQ

(Linux kernel CPUfreq subsystem) Clock scaling allows you to change the clock speed of the CPUs on the fly.

This is a nice method to save battery power, because the lower the clock speed is, the less power the CPU consumes.

PROCESSES

获取该log:执行ps -P

显示当前进程

PROCESSES AND THREADS

获取该log:执行ps -t -p -P

显示当前进程和线程

LIBRANK

获取该log:执行/system/xbin/librank

剔除不必要的library

BINDER FAILED TRANSACTION LOG

获取该log:读取文件/proc/binder/failed_transaction_log

BINDER TRANSACTION LOG

获取该log:读取文件/proc/binder/transaction_log

BINDER TRANSACTIONS

获取该log:读取文件/proc/binder/transactions

BINDER STATS

获取该log:读取文件/proc/binder/stats

BINDER PROCESS STATE

获取该log:读取文件/proc/binder/proc/*

bind相关的一些状态

FILESYSTEMS

获取该log:执行/system/bin/df

主要文件的一些容量使用状态(cache,sqlite,dev...)

PACKAGE SETTINGS

获取该log:读取文件/data/system/packages.xml

系统中package的一些状态(访问权限,路径...),类似Windows里面的一些lnk文件吧.

PACKAGE UID ERRORS

获取该log:读取文件/data/system/uiderrors.txt

错误信息

KERNEL LAST KMSG LOG

最新kernel message log

LAST RADIO LOG

最新radio log

KERNEL PANIC CONSOLE LOG

KERNEL PANIC THREADS LOG

控制台/线程的一些错误信息log

BACKLIGHTS

获取该log:获取LCD brightness读/sys/class/leds/lcd-backlight/brightness

获取该log:获取Button brightness读/sys/class/leds/button-backlight/brightness

获取该log:获取Keyboard brightness读/sys/class/leds/keyboard-backlight/brightness

获取该log:获取ALS mode读/sys/class/leds/lcd-backlight/als

获取该log:获取LCD driver registers读/sys/class/leds/lcd-backlight/registers

获取相关亮度的一些信息

(2)build.prop

VERSION INFO输出下列信息
当前时间
当前内核版本:可以读取文件(/proc/version)获得
显示当前命令:可以读取文件夹(/proc/cmdline)获得
显示系统build的一些属性:可以读取文件(/system/build.prop)获得
输出系统一些属性
gsm.version.ril-impl
gsm.version.baseband
gsm.imei
gsm.sim.operator.numeric
gsm.operator.alpha

(3)dumpsys

执行/system/bin/dumpsys后可以获得这个log.
经常会发现该log输出不完整,因为代码里面要求该工具最多只执行60ms,可能会导致log无法完全输出来.
可以通过修改时间参数来保证log完全输出.
信息:
Currently running services
DUMP OF SERVICE services-name(running)

Log Code Analysis

Site: ."frameworks"base"cmds"dumpstate"

相关Log程序的代码可以从上面目录获取

Log Analysis Experience

分析步骤

1.查看一些版本信息
确认问题的系统环境
2.查看CPU/MEMORY的使用状况
看是否有内存耗尽,CPU繁忙这样的背景情况出现.
3.分析traces
因为traces是系统出错以后输出的一些线程堆栈信息,可以很快定位到问题出在哪里. 
4.分析SYSTEM LOG
系统Log详细输出各种log,可以找出相关log进行逐一分析

实例分析

下面分析我写的一个测试例子,在OnCreate做一个死循环,这样主线程会被锁住,在按下硬件的Back之后会出现ANR的错误.
在traces中发现该程序的堆栈信息如下:

----- pid 20597 at 2010-03-15 01:29:53 -----
Cmd line: com.android.test
DALVIK THREADS:
"main" prio=5 tid=3 TIMED_WAIT
| group="main" sCount=1 dsCount=0 s=N obj=0x2aac6240 self=0xbda8
| sysTid=20597 nice=0 sched=0/0 cgrp=default handle=1877232296
at java.lang.VMThread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:1306)
at java.lang.Thread.sleep(Thread.java:1286)
at android.os.SystemClock.sleep(SystemClock.java:114)
at com.android.test.main.onCreate(main.java:20)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
at android.app.ActivityThread.access$2200(ActivityThread.java:119)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4363)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
at dalvik.system.NativeStart.main(Native Method)
"Binder Thread #2" prio=5 tid=11 NATIVE
| group="main" sCount=1 dsCount=0 s=N obj=0x2fb7c260 self=0x143860
| sysTid=20601 nice=0 sched=0/0 cgrp=default handle=1211376
at dalvik.system.NativeStart.run(Native Method)
"Binder Thread #1" prio=5 tid=9 NATIVE
| group="main" sCount=1 dsCount=0 s=N obj=0x2fb7c1a0 self=0x14c980
| sysTid=20600 nice=0 sched=0/0 cgrp=default handle=1207920
at dalvik.system.NativeStart.run(Native Method)
"Signal Catcher" daemon prio=5 tid=7 RUNNABLE
| group="system" sCount=0 dsCount=0 s=N obj=0x2fb7a1e8 self=0x126cc0
| sysTid=20599 nice=0 sched=0/0 cgrp=default handle=1269048
at dalvik.system.NativeStart.run(Native Method)
"HeapWorker" daemon prio=5 tid=5 VMWAIT
| group="system" sCount=1 dsCount=0 s=N obj=0x2e31daf0 self=0x135c08
| sysTid=20598 nice=0 sched=0/0 cgrp=default handle=1268528
at dalvik.system.NativeStart.run(Native Method)
----- end 20597 -----

该文件的堆栈结构从下往上进行分析
(1)栈底at dalvik.system.NativeStart.run(Native Method)
系统为当前的task(应用程式)启动一个专用的虚拟机 
(2) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
Activity Services是在后台负责管理Activity,它此时将测试例子的Activity启动起来了
(3)at com.android.test.main.onCreate(main.java:20)
启动测试程序
(4)栈顶at java.lang.VMThread.sleep(Native Method)
线程被sleep掉了,所以无法响应用户,出现ANR错误.

上面是对一个非常简单的问题的分析.

如果遇到比较复杂的问题还需要详细分析SYSTEM LOG.
1.比如网络异常,要通过SYSTEM LOG里面输出的网络链接信息来判断网络状态
2.数据传输,网络链接等耗时的操作需要分析SYSTEM LOG里面ActivityManager的响应时间

posted @ 2011-01-17 11:41 九宝 阅读(789) | 评论 (0)编辑 收藏

如何使Android应用程序获取系统权限【转】

转自:http://blog.csdn.net/liujian885/archive/2010/03/22/5404834.aspx

http://hi.baidu.com/donghaozheng/blog/item/30a00d4f9fca873baec3ab69.html

在 android 的API中有提供 SystemClock.setCurrentTimeMillis()函数来修改系统时间,可惜无论你怎么调用这个函数都是没用的,无论模拟器还是真机,在logcat中总会得到"Unable to open alarm driver: Permission denied ".这个函数需要root权限或者运行与系统进程中才可以用。

        本来以为就没有办法在应用程序这一层改系统时间了,后来在网上搜了好久,知道这个目的还是可以达到的。

        第一个方法简单点,不过需要在Android系统源码的环境下用make来编译:

        1. 在应用程序的AndroidManifest.xml中的manifest节点中加入android:sharedUserId="android.uid.system"这个属性。

        2. 修改Android.mk文件,加入LOCAL_CERTIFICATE := platform这一行

        3. 使用mm命令来编译,生成的apk就有修改系统时间的权限了。

        第二个方法麻烦点,不过不用开虚拟机跑到源码环境下用make来编译:

        1. 同上,加入android:sharedUserId="android.uid.system"这个属性。

        2. 使用eclipse编译出apk文件,但是这个apk文件是不能用的。

        3. 用压缩软件打开apk文件,删掉META-INF目录下的CERT.SF和CERT.RSA两个文件。

        4. 使用目标系统的platform密钥来重新给apk文件签名。这步比较麻烦,首先找到密钥文件,在我的Android源码目录中的位置是"build\target\product\security",下面的platform.pk8和platform.x509.pem两个文件。然后用Android提供的Signapk工具来签名,signapk的源代码是在"build\tools\signapk"下,用法为"signapk platform.x509.pem platform.pk8 input.apk output.apk",文件名最好使用绝对路径防止找不到,也可以修改源代码直接使用。

        这样最后得到的apk和第一个方法是一样的。

        最后解释一下原理,首先加入android:sharedUserId="android.uid.system"这个属性。通过Shared User id,拥有同一个User id的多个APK可以配置成运行在同一个进程中。那么把程序的UID配成android.uid.system,也就是要让程序运行在系统进程中,这样就有权限来修改系统时间了。

        只是加入UID还不够,如果这时候安装APK的话发现无法安装,提示签名不符,原因是程序想要运行在系统进程中还要有目标系统的platform key,就是上面第二个方法提到的platform.pk8和platform.x509.pem两个文件。用这两个key签名后apk才真正可以放入系统进程中。第一个方法中加入LOCAL_CERTIFICATE := platform其实就是用这两个key来签名。

        这也有一个问题,就是这样生成的程序只有在原始的Android系统或者是自己编译的系统中才可以用,因为这样的系统才可以拿到platform.pk8和platform.x509.pem两个文件。要是别家公司做的Android上连安装都安装不了。试试原始的Android中的key来签名,程序在模拟器上运行OK,不过放到G3上安装直接提示"Package ... has no signatures that match those in shared user android.uid.system",这样也是保护了系统的安全。

        最最后还说下,这个android:sharedUserId属性不只可以把apk放到系统进程中,也可以配置多个APK运行在一个进程中,这样可以共享数据,应该会很有用的。


博主补充:

signapk编译结束后在 android目录下/out/host/linux-x86/framework/signapk.jar
使用方法:java -jar signapk.jar platform.x509.pem platform.pk8 test.apk test_signed.apk
实践证明,第二种方法不需要删掉META-INF目录下的CERT.SF和CERT.RSA两个文件,直接signapk就可以。

posted @ 2010-12-20 16:06 九宝 阅读(337) | 评论 (0)编辑 收藏

Android Looper(转)

(1) Looper类别用来为一个线程开启一个消息循环。默认情况下Android中新诞生的线程是没有开启消息循环的。(主线程除外,主线程系统会自动为其创建Looper对象,开启消息循环)

Looper对象通过MessageQueue来存放消息和事件。一个线程只能有一个Looper,对应一个MessageQueue。

(2) 通常是通过Handler对象来与Looper交互的。Handler可看做是Looper的一个接口,用来向指定的Looper发送消息及定义处理方法。

默认情况下Handler会与其被定义时所在线程的Looper绑定,比如,在主线程中定义,其是与主线程的Looper绑定。

mainHandler = new Handler() 等价于new Handler(Looper.myLooper()).

Looper.myLooper():Return the Looper object associated with the current thread 获取当前进程的looper对象。

还有一个类似的 Looper.getMainLooper() 用于获取主线程的Looper对象。

(3) 在非主线程中直接new Handler() 会报如下的错误:

E/AndroidRuntime( 6173): Uncaught handler: thread Thread-8 exiting due to uncaught exception
E/AndroidRuntime( 6173): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

原因是非主线程中默认没有创建Looper对象,需要先调用Looper.prepare()启用Looper。

(4) Looper.loop(); 让Looper开始工作,从消息队列里取消息,处理消息。

注意:写在Looper.loop()之后的代码不会被执行,这个函数内部应该是一个循环,当调用mHandler.getLooper().quit()后,loop才会中止,其后的代码才能得以运行。

(5) 基于以上知识,可实现主线程给子线程(非主线程)发送消息。

把下面例子中的mHandler声明成类成员,在主线程通过mHandler发送消息即可。

(6) Android官方文档中Looper的介绍:

Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, call prepare() in the thread that is to run the loop, and then loop() to have it process messages until the loop is stopped.

Most interaction with a message loop is through the Handler class.

This is a typical example of the implementation of a Looper thread, using the separation ofprepare() and loop() to create an initial Handler to communicate with the Looper.

class LooperThread extends Thread {
      public Handler mHandler;
      
      public void run() {
          Looper.prepare();
          
          mHandler = new Handler() {
              public void handleMessage(Message msg) {
                  // process incoming messages here
              }
          };
          
          Looper.loop();
      }
}

posted @ 2010-12-20 15:13 九宝 阅读(384) | 评论 (0)编辑 收藏

android : px dip(转)

px (pixels) 像素
dip (device independent pixels) 设备独立像素
sp (scaled pixels - best for text size ) 放大像素,对文本大小最好
pt (points) 点
in (inches) 英寸
mm (millimeters) 毫米

很多网友可能发现在Android的layout文件中layout_width或layout_height有时候可能会指定具体的单位,比如有时候为px、dip或者sp等等。下面android123把常见的单位做下简单的介绍,比如说

px (pixels)像素 -- 一般我们HVGA代表320x480像素,这个用的比较多。

dip或dp (device independent pixels)设备独立像素 -- 这个和设备硬件有关,一般我们为了支持WVGA、HVGA和QVGA cwj推荐使用这个,不依赖像素。

sp (scaled pixels — best for text size)放大像素-- 主要处理字体的大小。


 下面的几个是不常用的,大家也知道这里android123就不再过多的赘述。


in (inches)英寸

mm (millimeters)毫米  

pt (points)点


px像素如何转为dip设备独立像素

最近有网友问如何将px像素转为dip独立设备像素,由于Android的设备分辨率众多,目前主流的为wvga,而很多老的设备为hvga甚至低 端的qvga,对于兼容性来说使用dip无非是比较方便的,由于他和分辨率无关和屏幕的密度大小有关,所以推荐使用,不过这里android123提示大 家,ophone os的手机对于dip的支持糟糕透了,显示的结果会放大很多,同时黑色的主题会导致常规的黑色文字让用户无法分辨。

  px= (int) (dip*density+0.5f) //这里android开发网提示大家很多网友获取density的方法存在问题,从资源中获取的是静态定义的,一般为1.0对于HVGA是正好的,而对于wvga这样的应该从WindowsManager中获取,WVGA为1.5


QVGA HVGA WVGA区别

文章分类:移动开发

QVGA即"Quarter VGA"。顾名思义即VGA的四分之一尺寸,亦即在液晶屏幕(LCD)上输出的分辨率是240×320像素。QVGA支持屏幕旋转,可以开发出相应的程序,以显示旋转90°、180°、270°屏幕位置。由HandEra公司发布。多用于手持/移动设备。   需要说明的是有些媒体把QVGA屏幕当成与TFT和TFD等LCD材质相同的东西是错误的,QVGA屏幕的说法多见与日本的一些手机中,目前采用微软Pocket PC操作系统的智能手机屏幕也大多是320×240像素的QVGA屏幕。   所谓QVGA液晶技术,就是在液晶屏幕上输出的分辨率是240×320的液晶输出方式。这个分辨率其实和屏幕本身的大小并没有关系。比如说,如果2.1英寸液晶显示屏幕可以显示240×320分辨率的图像,就叫做“QVGA 2.1英寸液晶显示屏”;如果3.8英寸液晶显示屏幕可以显示240×320的图像,就叫做“QVGA 3.8英寸液晶显示屏”,以上两种情况虽然具有相同的分辨率,但是由于尺寸的不同实际的视觉效果也不同,一般 HVGA 即VGA(640*480)的一半,分辨率为(480*320),(3:2宽高比)   它是用于各种各样的PDA设备,首先是2002年的索尼Clie PEG - NR70, 来说屏幕小的一个画面自然也会细腻一些。 WVGA 数码产品屏幕材质的一种,VGA的另一种形式,比VGA分辨率高,别名 : Wide VGA, ,其分辩率为800×480象素。是扩大了VGA(640×480)的分辨率。应用于PDA和手机等,因为很多网页的宽度都是800,所以WVGA的屏幕会更加适和于浏览网页,可以说是未来手持设备的分辨率的大趋势

posted @ 2010-12-16 16:35 九宝 阅读(1153) | 评论 (0)编辑 收藏

drawable各个目录

drawable-hdpi(高分辨率)目录下
这个主要是为了支持多分辨率的.
hdpi里面主要放高分辨率的图片,如WVGA (480x800),FWVGA (480x854)
mdpi里面主要放中等分辨率的图片,如HVGA (320x480)
ldpi里面主要放低分辨率的图片,如QVGA (240x320)
系统会根据机器的分辨率来分别到这几个文件夹里面去找对应的图片

posted @ 2010-12-09 16:24 九宝 阅读(279) | 评论 (0)编辑 收藏

andorid padding margin


android:padding 属性允许你设置相同的4个方向的间距值,组件的内容在间距内的中间。如果你要四个不同数值的间距值,,可以分别使用 android:paddingLeft,android:paddingRight,android:paddingTop和 android:paddingBottom。间距值是一个具体的数值,如果要5像素,则可以对应填写”5px”.
如 果你应用组件的默认背景(例如,通过android:backgound属性),背景将会同时显示在间距和组件上。为了避免这种情况,用 padding,还不如用margin,这可以只增加空白的空间,并不会撑大组件。你可以通过android:layoout_margin属性来实现。
例如:<com.android.motoswitch.HandleView
            style="@style/HotseatButton"
            android:id="@+id/all_apps_button"
            android:layout_centerHorizontal="true"
            android:layout_alignParentBottom="true"
            android:src="@drawable/all_apps_button"
            switcher:direction="horizontal"
            />

posted @ 2010-12-08 15:38 九宝 阅读(395) | 评论 (0)编辑 收藏

(转) Android核心分析(22)-----Android应用框架之Activit

Android核心分析(22)-----Android应用框架之Activity 收藏

From  http://blog.csdn.net/maxleng/archive/2010/05/24/5621349.aspx

3 Activity设计框架

3.1 外特性空间的Activity

    我们先来看看,Android应用开发人员接触的外特性空间中的Activity,对于AMS来讲,这个Activity就是客服端的Activity。应用程序员在建立Android应用时,构建Activity的子类就是Andoid外特性空间展现的接口。我们可以从下面的简单的例子描述看看Activity,到底如何建立的。

DemoActivity extend Activity

{

     onCreate

    onResume

    onPause

    onStop

}

    在Android的外特性空间(SDK)中,Android应用程序员根本不知道进程是什么时候起来的,系统消息是如何传递过来的。这个DemoActivity是如何实例化的呢?并且该Activity是托管在哪个进程的呢?本节的分析将给出答案。

我们从ActivityThread中可以看到在应用进程中的Activity都被放置在mActivities中。

image_thumb3

    这些ActivityRecord记录了应用进程中,程序员建立的Activity子类的实例,我们称之为外特性空间的Activity。这些Activity类实例是放在应用程序端进行实际交互的Activity,而为了管理这些Activity,AMS内核中还有一个影子Activity,被称为HistoryRecord。

3.2 Activity与HistoryRecord的关系

     在整个系统中,Activity实际上有两个实体。一个在应用进程中跟应用程序员打交道的Activity,一个是在AMS的中具有管理功能的History Record。应用进程中的Activity都登记ActivityThread实例中的mActivity数组中,而在AM端,HistroytRecord实例放置在mHistroy栈中。mHistory栈是Android管理Activity的场所,放置在栈顶的就是User看到的处于活动状态的Activity。

Activity与HistrotyRecord的关系图可以表示如下:

image_thumb6

       Activity的内核实体是依靠在ProcessRecord的成员变量中,通过ProcessRecord我们可以访问到所有的属于该Process的Activity。而在ProcessRecord记录了与应用进程之间的联系:IActivtityThread接口。通过该接口,可以访问到所对应的Activity的方法。在Launch Activity时,AMS将对应的HistoryRecord作为token传递到客服端和客服端的Activity建立联系。在AMS中Activity状态变化时,将通过该联系找到客服端的Activity,从而将消息或者动作传递应用程序面对的接口:xxxActivity。

3.3 Actvity的Launch过程

1)发起请求startActivity(intent)

2)Activity Service Manager接收到请求执行StartActivity函数。

      建立:HistoryRecord实例r.

      将r 加入到mHistory顶。

(3)通过app.thread.scheduleLaunchActvity( app,r)@ActivityThread.java

(4)在App应用中建立新的ActivityRecord。

(5)建立新的Activity对象并放入到ActivityRecord中。

(6)将ActivityRecord加入到mActivites@ActivityThread

(7)发起Activity.onCreate(..),,该onCreate就是在你的应用程序XXXActivity中的onCreate。

  image_thumb10

3.4 Activity的Resume

(1)Activity什么时候被Resume

image_thumb13

(2)Rusume的过程

    通过该过程的研究我们会进一步的了解到AMS与应用进程的交互过程。

在AMS端,满足resume条件都会调用:Resume的核心函数:resumeTopActivityLocked@ActivityManagerService

XXX当前栈顶的HistroyRecord

1)窗口切换:隐藏前一个Activity的窗口,

2)更新LRUList,(LRUList是淘汰应用程序的依据之一)

3) XXX.app.thread.scheduleResumeActivity(XXX,

                        isNextTransitionForward());

4)completeResumeLocked

     setFocusedActivityLocked

        mFocusActivity=xxx  //此时焦点Actvitiy切换了。

       WM.setFocusedApp(xxx,

       mWindowManager.executeAppTransition();

       mNoAnimActivities.clear();

在应用程序端:

(5)scheduleResumeActivity

handleResumeActivity(IBinder token, boolean clearHide, boolean isForward) {

ActivityRecord r = performResumeActivity(token, clearHide);

     ActivityRecord r = mActivities.get(token);

     r.activity.performResume()

              performResume

整个Resume的过程如下:

image_thumb16

posted @ 2010-09-25 15:39 九宝 阅读(325) | 评论 (0)编辑 收藏

(转)Android核心分析(21)----Android应用框架之AndroidApplication

From  http://blog.csdn.net/maxleng/archive/2010/05/24/5621345.aspx

Android Application

    Android提供给开发程序员的概念空间中Application只是一个松散的表征概念,没有多少实质上的表征。在Android实际空间中看不到实际意义上的应用程序的概念,即使有一个叫Application的类,这个也就是个应用程序上下文状态,是一个极度弱化的概念。Application只是一个空间范畴的概念,Application就是Activity,Service之类的组件上下文描述。Application并不是Android的核心概念,而Activity才是Android的核心概念。

    从Android的SDK文档中,我们知道一般情况Android应用程序是由以下四种组件构造而成的:Activity,Broadcast Intent Receiver,服务(Service),内容提供器(Content Provider)。我们可以使用下面的图来表示一下Android的概念空间。这些组件依附于应用程序中,应用程序并不会一开始就建立起来,而是在这些组件建立起来后,需要运行时,才开始建立应用程序对象。

image

2.1应用进程名称

    为什么要从应用进程名称开始?作为内核研究,我们还是回到问题的最本质处:不管Activity,Service等组件如何设计和运行,它要提供服务,就必须要依附在Linux的进程上,建立消息循环,组件才能够真正的运作。Activity实例是如何Hosting在Linux进程上的?这个是我们首先想要弄明白的。

我们在项目中看到android:process="string"这个定义。

allowClearUserData=["true" | "false"] 
android:
allowTaskReparenting=["true" | "false"] 
android:
backupAgent="string" 

android:label="string resource" 
android:
manageSpaceActivity="string" 
android:
name="string" 
android:
permission="string" 
android:
persistent=["true" | "false"] 
android:
process="string" 
android:
restoreAnyVersion=["true" | "false"] 
android:
taskAffinity="string" 
android:
theme="resource or theme" > 
    . . . 

在SDK用已经描述的很清楚到了。

android:process

The name of a process where all components of the application should run. Each component can override this default by setting its own process attribute.

By default, Android creates a process for an application when the first of its components needs to run. All components then run in that process. The name of the default process matches the package name set by the element.

By setting this attribute to a process name that's shared with another application, you can arrange for components of both applications to run in the same process — but only if the two applications also share a user ID and be signed with the same certificate.

为什么要提出这么一个定义?android:process名称。

    默认状态下,Activity Manager Service在应用程序的第一个组件需要运行时将会为应用程序建立一个进程,而这个进程的名字就是android:process=”string”所指定,缺省的是应用程序包的名字。该进程一旦建立,后面的该应用的组件都将运行在该进程中,他们绑定的根据就是这个Android:Process指定的名称,因为在他们都在同一个应用程序包里,也就具有了同样的进程名字,于是他们都托管在了同一进程中。组件将通过ClassLoader从Package中获取到应用程序的信息。

    在建立Actvitiy时,如果在应用进程端没有应用对象,系统在该过程中利用makeApplication建立一个Application对象,实例化"android.app.Application",建立一个应用程序上下文完成例如资源,package等信息管理。

2.2  ActivityThread运行框架

    在分析中,我们可以看到真正对应应用进程的不是Application而是ActivityThread。我们从实际的应用堆栈可以看到:

NaiveStart.main()

        ZygoteInit.main

           ZygoteInit$MethodAndArgsCall.run

              Method.Invoke

                                       method.invokeNative

                     ActivityThread.main()

                         Looper.loop()

                                                                 ....

    每个应用程序都以ActivityThread.main()为入口进入到消息循环处理。对于一个进程来讲,我们需要这个闭合的处理框架。

image

    ActivitiyThread是应用程序概念空间的重要概念,他建立了应用进程运行的框架,并提供了一个IActivityThread接口作为与Activity Manager Service的通讯接口.通过该接口AMS可以将Activity的状态变化传递到客户端的Activity对象。

2.3 ActivitiyThread的建立

为了叙述的方便我将Actvitiy Manager Service简写成AMS。

    在AMS中关于应用程序的概念是ProcessRecord,请求都是从Activity,Service…等开始的,在Activity需要Resume时,此时如果与Activity相关的应用进程没有起来,AM则启动应用进程。

AMS与应用进程的绑定分为两个部分,第一部分就是AM建立应用进程,第二部分就是应用进程Attach到AM,与AM建立通讯通道。

1)创建建立进程:startProcessLocked(processName,Appinfo.uid)。该函数在StartSecificActivityLocked等调用。

(1)建立ProcessRecord对象app,并将该对象添加到mProcessNames中。应用对象在mProcessNames中使用应用名字和uid来标识自己。如果在同一个Package中的Activity,如果都使用默认设置,那么这些Activity都会托管在同一个进程中,这是因为他们在带的ApplicationInfo中的ProcessName都是一样的。

image 

image

mPidsSelfLocked数组记录了PID,这个将会在应用进程跑起来后,将自己Attach到AM时,根据pid找到自己的前世:ProcessRecord.

2)android.app.ActivityThread进程启动

     Android.app.ActivityThread进程建立后,将跳入到ActivityThread的main函数开始运行,进入消息循环。image

    应用进程使用thread.attach()发起AMS的AttachApplicationLocked调用,并传递 ActvitiyThread对象和CallingPid。AttachApplicationLocked将根据CallingPid在mPidsSelfLocked找到对应的ProcessRecord实例app,将ActvitiyThread放置app.thread中。这样应用进程和AMS建立起来双向连接。AM可以使用AIDL接口,通过app.thread可以访问应用进程的对象。

    应用程序通过ActivityThread提供的框架,建立消息循环Looper和Handler。从前面的相关章节我们知道有Looper和Handler,整个系统就可以运作了。

为了更为系统的了解应用程序的建立时序及其涉及到数据操作,我给出了应用进程的建立过程示意图:

 image

posted @ 2010-09-25 15:38 九宝 阅读(728) | 评论 (0)编辑 收藏

仅列出标题
共9页: 上一页 1 2 3 4 5 6 7 8 9 下一页