Android系统启动源代码调查分析

时间:2019-05-14 05:52:04下载本文作者:会员上传
简介:写写帮文库小编为你整理了多篇相关的《Android系统启动源代码调查分析》,但愿对你工作学习有帮助,当然你在写写帮文库还可以找到更多《Android系统启动源代码调查分析》。

第一篇:Android系统启动源代码调查分析

Android系统启动调查。

目的:Android程序入口在哪里?Mainifest配置文件如何加载实例化?从系统层到应用层如何使用?

目标从系统角度来了解Android启动过程,通过下载源代码并且根据源代码从底层开始跟踪,跟着方法走一遍Android启动过程。了解Zygote进程是什么?

开机一开始:Linux启动这一层,主要包括了两块:BootLoader(嵌入式系统的引导程序)和Kernel(Linux内核层,驱动层)第二块:Android系统启动。

我们都知道,Linux系统启动,定义了一个Init.rc这个系统启动的配置文件(放在System/bin文件下面)。

Init.rc启动的时候,最开始启动了SystemManager守护进程,它的源代码是一个Java文件,守护进程是一个与界面无关,会持续运行在后台,用来接收响应,并且维持系统运营的。

在启动servicemanager的同时,再来启动Zygote,Zygote实际上启动的是:app_main.cpp的系统文件.这个文件的main()方法,会调用Android_Runtime.cpp的文件中的start()方法,这个方法通过JNI机制,来调用ZygoteInit.java孵化器初始文件,这个文件的Main()函数,将会去调用所有进程。

这个ZygoteInit文件的main()函数,这个函数通过JNI机制调用了FrameWrok中的SystemServer文件,这个文件有三个函数:main(),init1()和init2()方法。

Init1()方法会通过JNI机制再去调用com_Android__server_SystemService.java的原生态文件,去实现系统初始化的操作,(调用System_init.cpp)。

当系统初始化工作做完之后,系统反过来会调用SystemServer文件下面的init2()方法,会通过runtime方法调用ServerThread进程去调用激活其他的所有进程。

第三块:应用程序启动(下次再讲)。

使用工具:【代码分析工具】source Insight 【源代码】 Android 源代码包

操作步骤:

在下载好Android SDK 安装包之后(如果没有下载好请移步这里)

【配置代码分析工具】

打开source Insight 软件,来配置Android源代码。

“项目”→“新建项目”

在“新项目名”填写:“Android 14”(Android 第14个版本,代表Android V4.0.3)在“项目文件储存位置”填写:SDK源代码包的位置

继续进行配置,点击确定。

选中右边的所有文件夹,点击“添加所有”按钮,将这个版本的源代码全部导入。

应用级别:选中将所有的子集目录,下级子目录中的所有文件都导入查找项目。

进行检索。。。

一共找到了“213720”个文件,是否导入?选中“Yes”

导入文件,索引建立

这时候,查看正下方,项目文件(213720)已经全部导入,项目准备完毕。可以进行调查了。

这时候你看到的右边工具栏,就是我们可以用来方便查找的搜索栏,输入对应的关键字即可。

切入正题,查找Android系统启动文件

【查找Init文件】启动方法会初始化MainiFest.xml配置文件,配置文件再去调用里面的配置,但是启动方法何时启动的调查,还未找到源头,只知道一切事物的源头,从这里开始。

原代码如下:

service console /system/bin/sh(启动Linux内核)

console

disabled

user shell

group log

on property:ro.secure=0

start console

# adbd is controlled by the persist.service.adb.enable system property service adbd /sbin/adbd

disabled

# adbd on at boot in emulator on property:ro.kernel.qemu=1

start adbd

on property:persist.service.adb.enable=1

start adbd

on property:persist.service.adb.enable=0

stop adbd

service servicemanager /system/bin/servicemanager(启动服务管理进程)

user system

critical

onrestart restart zygote

onrestart restart media

service vold /system/bin/vold

socket vold stream 0660 root mount

ioprio be 2

service netd /system/bin/netd

socket netd stream 0660 root system

socket dnsproxyd stream 0660 root inet

service debuggerd /system/bin/debuggerd

service ril-daemon /system/bin/rild

socket rild stream 660 root radio

socket rild-debug stream 660 radio system

user root

group radio cache inet misc audio sdcard_rw

service zygote /system/bin/app_process-Xzygote /system/bin--zygote--start-system-server

socket zygote stream 666

onrestart write /sys/android_power/request_state wake

onrestart write /sys/power/state on

onrestart restart media

onrestart restart netd

OK,现在先调查(ServerManager)这个启动进程。

在system/core/libsysutils/src 目录下(系统级启动进程)

(启动孵化器进程)

在左侧点击start方法

这就是守护进程中的源代码之一,start()方法 ServiceManager::ServiceManager(){ } int ServiceManager::start(const char *name){ //如果进程已经启动,那么打印日志:“XX进程已经启动”

if(isRunning(name)){

SLOGW(“Service '%s' is already running”, name);

return 0;

}

SLOGD(“Starting service '%s'”, name);

property_set(“ctl.start”, name);

int count = 200;

while(count--){

sched_yield();

if(isRunning(name))

break;

}

if(!count){

SLOGW(“Timed out waiting for service '%s' to start”, name);

errno = ETIMEDOUT;

return-1;

}

SLOGD(“Sucessfully started '%s'”, name);

return 0;}

再来看同时启动的app_main的源代码,我们去查看一下它的main函数

int main(int argc, const char* const argv[]){

// These are global variables in ProcessState.cpp

mArgC = argc;

mArgV = argv;

mArgLen = 0;

for(int i=0;i

mArgLen += strlen(argv[i])+ 1;

}

mArgLen--;

AppRuntime runtime;

const char *arg;

const char *argv0;

argv0 = argv[0];

// Process command line arguments

// ignore argv[0]

argc--;

argv++;

// Everything up to '--' or first non '-' arg goes to the vm

int i = runtime.addVmArguments(argc, argv);

// Next arg is parent directory

if(i < argc){

runtime.mParentDir = argv[i++];

}

// Next arg is startup classname or “--zygote”

if(i < argc){

arg = argv[i++];

if(0 == strcmp(“--zygote”, arg)){

bool startSystemServer =(i < argc)?

strcmp(argv[i], “--start-system-server”)== 0 : false;

setArgv0(argv0, “zygote”);

//设置了一个进程名叫zygote的进程,通过runtime来启动ZygoteInit文件中的startSystemServer方法

set_process_name(“zygote”);

runtime.start(“com.android.internal.os.ZygoteInit”,startSystemServer);

} else {

set_process_name(argv0);

runtime.mClassName = arg;

// Remainder of args get passed to startup class main()

runtime.mArgC = argc-i;

runtime.mArgV = argv+i;

LOGV(“App process is starting with pid=%d, class=%s.n”,getpid(), runtime.getClassName());

runtime.start();

}

} else {

LOG_ALWAYS_FATAL(“app_process: no class name or--zygote supplied.”);

fprintf(stderr, “Error: no class name or--zygote supplied.n”);

app_usage();

return 10;

} } 调查一下runtime的类。AppRuntime,这就是android系统的运行时类,它启动了zygote孵化器进程,用来孵化Davlik虚拟机的。

runtime.start(“com.android.internal.os.ZygoteInit”,startSystemServer);所涉及到的ZygoteInit文件。

找到ZygoteInit文件(FrameWork里面的一个java类)。先去看看Main函数。

public static void main(String argv[]){

try {

VMRuntime.getRuntime().setMinimumHeapSize(5 * 1024 * 1024);

// Start profiling the zygote initialization.SamplingProfilerIntegration.start();

registerZygoteSocket();

EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,SystemClock.uptimeMillis());

preloadClasses();

//cacheRegisterMaps();

preloadResources();

EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,SystemClock.uptimeMillis());

// Finish profiling the zygote initialization.SamplingProfilerIntegration.writeZygoteSnapshot();

// Do an initial gc to clean up after startup

gc();

// If requested, start system server directly from Zygote

if(argv.length!= 2){

throw new RuntimeException(argv[0] + USAGE_STRING);

}

if(argv[1].equals(“true”)){ //如果输入参数为真,我们就启动系统服务

startSystemServer();

} else if(!argv[1].equals(“false”)){

throw new RuntimeException(argv[0] + USAGE_STRING);

}

Log.i(TAG, “Accepting command socket connections”);

if(ZYGOTE_FORK_MODE){ //如果孵化器一直是交叉模式,就启动运行交叉模式函数;否则就选择另一个循环模式

runForkMode();

} else {

runSelectLoopMode();

}

closeServerSocket();

} catch(MethodAndArgsCaller caller){

caller.run();

} catch(RuntimeException ex){

Log.e(TAG, “Zygote died with exception”, ex);

closeServerSocket();

throw ex;

}

}

我们继续查看,如果参数为真的情况下,ZygoteInit文件中的,startSystemServer()函数的源代码。

/**

* Prepare the arguments and fork for the system server process.*/

private static boolean startSystemServer()

throws MethodAndArgsCaller, RuntimeException {

/* Hardcoded command line to start the system server */

String args[] = {

“--setuid=1000”,“--setgid=1000”,“--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003”,“--capabilities=130104352,130104352”,“--runtime-init”,“--nice-name=system_server”,“com.android.server.SystemServer”,//这个虚拟机的名字叫system Server

};

ZygoteConnection.Arguments parsedArgs = null;

int pid;

try {

parsedArgs = new ZygoteConnection.Arguments(args);

/*

* Enable debugging of the system process if *either* the command line flags

* indicate it should be debuggable or the ro.debuggable system property

* is set to “1”

*/

int debugFlags = parsedArgs.debugFlags;

if(“1”.equals(SystemProperties.get(“ro.debuggable”)))

debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;

/* Request to fork the system server process */

pid = Zygote.forkSystemServer(parsedArgs.uid, parsedArgs.gid,parsedArgs.gids, debugFlags, null,parsedArgs.permittedCapabilities,parsedArgs.effectiveCapabilities);

} catch(IllegalArgumentException ex){

throw new RuntimeException(ex);

}

/* For child process */

if(pid == 0){

handleSystemServerProcess(parsedArgs);

}

return true;

}

我们继续去查看 system Server的源代码

main函数:

/**

* This method is called from Zygote to initialize the system.This will cause the native

* services(SurfaceFlinger, AudioFlinger, etc..)to be started.After that it will call back

* up into init2()to start the Android services.*/

native public static void init1(String[] args);//Init1()函数却是个空函数

public static void main(String[] args){

if(System.currentTimeMillis()< EARLIEST_SUPPORTED_TIME){

// If a device's clock is before 1970(before 0), a lot of

// APIs crash dealing with negative numbers, notably

// java.io.File#setLastModified, so instead we fake it and

// hope that time from cell towers or NTP fixes it

// shortly.Slog.w(TAG, “System clock is before 1970;setting to 1970.”);

SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);

}

if(SamplingProfilerIntegration.isEnabled()){

SamplingProfilerIntegration.start();

timer = new Timer();

timer.schedule(new TimerTask(){

@Override

public void run(){

SamplingProfilerIntegration.writeSnapshot(“system_server”);

}

}, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);

}

// The system server has to run all of the time, so it needs to be

// as efficient as possible with its memory usage.VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

System.loadLibrary(“android_servers”);

init1(args);// main()函数中,会调用到 init1()的方法。

}

public static final void init2(){

Slog.i(TAG, “Entered the Android system server!”);

Thread thr = new ServerThread();

thr.setName(“android.server.ServerThread”);

thr.start();

}

因为通过调查发现,SystemServer文件的main()函数调用的init1()函数,是一个空方法,native public static void init1(String[] args);

但是根据JNI调用机制,我们可以在同名文件夹(framework/base/services/)下找到JNL目录,然后找到和系统相关的com_android_server_SystemServer.java文件

使用“C”的动态链接嗲用system_init 的方法。它去回调Init2的方法

我们继续看看SystemServer方法的Init2()方法是看什么用的。

去调查一下ServerThread()方法是干什么用的?这个内部类ServerThread就是启动,并且实例化每一个系统进程的线程类

class ServerThread extends Thread {

private static final String TAG = “SystemServer”;

private final static boolean INCLUDE_DEMO = false;

private static final int LOG_BOOT_PROGRESS_SYSTEM_RUN = 3010;

private ContentResolver mContentResolver;

private class AdbSettingsObserver extends ContentObserver {

public AdbSettingsObserver(){

super(null);

}

@Override

public void onChange(boolean selfChange){

boolean enableAdb =(Settings.Secure.getInt(mContentResolver,Settings.Secure.ADB_ENABLED, 0)> 0);

// setting this secure property will start or stop adbd

SystemProperties.set(“persist.service.adb.enable”, enableAdb ? “1” : “0”);

}

}

@Override

public void run(){

EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN,SystemClock.uptimeMillis());

Looper.prepare();

android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);

BinderInternal.disableBackgroundScheduling(true);

android.os.Process.setCanSelfBackground(false);

// Check whether we failed to shut down last time we tried.{

final String shutdownAction = SystemProperties.get(ShutdownThread.SHUTDOWN_ACTION_PROPERTY, “");

if(shutdownAction!= null && shutdownAction.length()> 0){

boolean reboot =(shutdownAction.charAt(0)== '1');

final String reason;

if(shutdownAction.length()> 1){

reason = shutdownAction.substring(1, shutdownAction.length());

} else {

reason = null;

}

ShutdownThread.rebootOrShutdown(reboot, reason);

}

}

String factoryTestStr = SystemProperties.get(”ro.factorytest“);

int factoryTest = ”“.equals(factoryTestStr)? SystemServer.FACTORY_TEST_OFF

: Integer.parseInt(factoryTestStr);

LightsService lights = null;

PowerManagerService power = null;

BatteryService battery = null;

ConnectivityService connectivity = null;

IPackageManager pm = null;

Context context = null;

WindowManagerService wm = null;

BluetoothService bluetooth = null;

BluetoothA2dpService bluetoothA2dp = null;

HeadsetObserver headset = null;

DockObserver dock = null;

UsbService usb = null;

UiModeManagerService uiMode = null;

RecognitionManagerService recognition = null;

ThrottleService throttle = null;

// Critical services...try {

Slog.i(TAG, ”Entropy Service“);

ServiceManager.addService(”entropy“, new EntropyService());

Slog.i(TAG, ”Power Manager“);

power = new PowerManagerService();

ServiceManager.addService(Context.POWER_SERVICE, power);

Slog.i(TAG, ”Activity Manager“);

context = ActivityManagerService.main(factoryTest);

Slog.i(TAG, ”Telephony Registry“);

ServiceManager.addService(”telephony.registry“, new TelephonyRegistry(context));

AttributeCache.init(context);

Slog.i(TAG, ”Package Manager“);

pm = PackageManagerService.main(context,factoryTest!= SystemServer.FACTORY_TEST_OFF);

ActivityManagerService.setSystemProcess();

mContentResolver = context.getContentResolver();

// The AccountManager must come before the ContentService

try {

Slog.i(TAG, ”Account Manager“);

ServiceManager.addService(Context.ACCOUNT_SERVICE,new AccountManagerService(context));

} catch(Throwable e){

Slog.e(TAG, ”Failure starting Account Manager“, e);

}

Slog.i(TAG, ”Content Manager“);

ContentService.main(context,factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL);

Slog.i(TAG, ”System Content Providers“);

ActivityManagerService.installSystemProviders();

Slog.i(TAG, ”Battery Service“);

battery = new BatteryService(context);

ServiceManager.addService(”battery“, battery);

Slog.i(TAG, ”Lights Service“);

lights = new LightsService(context);

Slog.i(TAG, ”Vibrator Service“);

ServiceManager.addService(”vibrator“, new VibratorService(context));

// only initialize the power service after we have started the

// lights service, content providers and the battery service.power.init(context, lights, ActivityManagerService.getDefault(), battery);

Slog.i(TAG, ”Alarm Manager“);

AlarmManagerService alarm = new AlarmManagerService(context);

ServiceManager.addService(Context.ALARM_SERVICE, alarm);

Slog.i(TAG, ”Init Watchdog“);

Watchdog.getInstance().init(context, battery, power, alarm,ActivityManagerService.self());

Slog.i(TAG, ”Window Manager“);

wm = WindowManagerService.main(context, power,factoryTest!= SystemServer.FACTORY_TEST_LOW_LEVEL);

ServiceManager.addService(Context.WINDOW_SERVICE, wm);

((ActivityManagerService)ServiceManager.getService(”activity“)).setWindowManager(wm);

// Skip Bluetooth if we have an emulator kernel

// TODO: Use a more reliable check to see if this product should

// support Bluetooth-see bug 988521

if(SystemProperties.get(”ro.kernel.qemu“).equals(”1“)){

Slog.i(TAG, ”Registering null Bluetooth Service(emulator)“);

ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE, null);

} else if(factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL){

Slog.i(TAG, ”Registering null Bluetooth Service(factory test)“);

ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE, null);

} else {

Slog.i(TAG, ”Bluetooth Service“);

bluetooth = new BluetoothService(context);

ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE, bluetooth);

bluetooth.initAfterRegistration();

bluetoothA2dp = new BluetoothA2dpService(context, bluetooth);

ServiceManager.addService(BluetoothA2dpService.BLUETOOTH_A2DP_SERVICE,bluetoothA2dp);

int bluetoothOn = Settings.Secure.getInt(mContentResolver,Settings.Secure.BLUETOOTH_ON, 0);

if(bluetoothOn > 0){

bluetooth.enable();

}

}

} catch(RuntimeException e){

Slog.e(”System“, ”Failure starting core service“, e);

}

DevicePolicyManagerService devicePolicy = null;

StatusBarManagerService statusBar = null;

InputMethodManagerService imm = null;

AppWidgetService appWidget = null;

NotificationManagerService notification = null;

WallpaperManagerService wallpaper = null;

LocationManagerService location = null;

if(factoryTest!= SystemServer.FACTORY_TEST_LOW_LEVEL){

try {

Slog.i(TAG, ”Device Policy“);

devicePolicy = new DevicePolicyManagerService(context);

ServiceManager.addService(Context.DEVICE_POLICY_SERVICE, devicePolicy);

} catch(Throwable e){

Slog.e(TAG, ”Failure starting DevicePolicyService“, e);

}

try {

Slog.i(TAG, ”Status Bar“);

statusBar = new StatusBarManagerService(context);

ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);

} catch(Throwable e){

Slog.e(TAG, ”Failure starting StatusBarManagerService“, e);

}

try {

Slog.i(TAG, ”Clipboard Service“);

ServiceManager.addService(Context.CLIPBOARD_SERVICE,new ClipboardService(context));

} catch(Throwable e){

Slog.e(TAG, ”Failure starting Clipboard Service“, e);

}

try {

Slog.i(TAG, ”Input Method Service“);

imm = new InputMethodManagerService(context, statusBar);

ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);

} catch(Throwable e){

Slog.e(TAG, ”Failure starting Input Manager Service“, e);

}

try {

Slog.i(TAG, ”NetStat Service“);

ServiceManager.addService(”netstat“, new NetStatService(context));

} catch(Throwable e){

Slog.e(TAG, ”Failure starting NetStat Service“, e);

}

try {

Slog.i(TAG, ”NetworkManagement Service“);

ServiceManager.addService(Context.NETWORKMANAGEMENT_SERVICE,NetworkManagementService.create(context));

} catch(Throwable e){

Slog.e(TAG, ”Failure starting NetworkManagement Service“, e);

}

try {

Slog.i(TAG, ”Connectivity Service“);

connectivity = ConnectivityService.getInstance(context);

ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);

} catch(Throwable e){

Slog.e(TAG, ”Failure starting Connectivity Service“, e);

}

try {

Slog.i(TAG, ”Throttle Service“);

throttle = new ThrottleService(context);

ServiceManager.addService(Context.THROTTLE_SERVICE, throttle);

} catch(Throwable e){

Slog.e(TAG, ”Failure starting ThrottleService“, e);

}

try {

Slog.i(TAG, ”Accessibility Manager“);

ServiceManager.addService(Context.ACCESSIBILITY_SERVICE,new AccessibilityManagerService(context));

} catch(Throwable e){

Slog.e(TAG, ”Failure starting Accessibility Manager“, e);

}

try {

/*

* NotificationManagerService is dependant on MountService,*(for media / usb notifications)so we must start MountService first.*/

Slog.i(TAG, ”Mount Service“);

ServiceManager.addService(”mount“, new MountService(context));

} catch(Throwable e){

Slog.e(TAG, ”Failure starting Mount Service“, e);

}

try {

Slog.i(TAG, ”Notification Manager“);

notification = new NotificationManagerService(context, statusBar, lights);

ServiceManager.addService(Context.NOTIFICATION_SERVICE, notification);

} catch(Throwable e){

Slog.e(TAG, ”Failure starting Notification Manager“, e);

}

try {

Slog.i(TAG, ”Device Storage Monitor“);

ServiceManager.addService(DeviceStorageMonitorService.SERVICE,new DeviceStorageMonitorService(context));

} catch(Throwable e){

Slog.e(TAG, ”Failure starting DeviceStorageMonitor service“, e);

}

try {

Slog.i(TAG, ”Location Manager“);

location = new LocationManagerService(context);

ServiceManager.addService(Context.LOCATION_SERVICE, location);

} catch(Throwable e){

Slog.e(TAG, ”Failure starting Location Manager“, e);

}

try {

Slog.i(TAG, ”Search Service“);

ServiceManager.addService(Context.SEARCH_SERVICE,new SearchManagerService(context));

} catch(Throwable e){

Slog.e(TAG, ”Failure starting Search Service“, e);

}

if(INCLUDE_DEMO){

Slog.i(TAG, ”Installing demo data...“);

(new DemoThread(context)).start();

}

try {

Slog.i(TAG, ”DropBox Service“);

ServiceManager.addService(Context.DROPBOX_SERVICE,new DropBoxManagerService(context, new File(”/data/system/dropbox“)));

} catch(Throwable e){

Slog.e(TAG, ”Failure starting DropBoxManagerService“, e);

}

try {

Slog.i(TAG, ”Wallpaper Service“);

wallpaper = new WallpaperManagerService(context);

ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper);

} catch(Throwable e){

Slog.e(TAG, ”Failure starting Wallpaper Service“, e);

}

try {

Slog.i(TAG, ”Audio Service“);

ServiceManager.addService(Context.AUDIO_SERVICE, new AudioService(context));

} catch(Throwable e){

Slog.e(TAG, ”Failure starting Audio Service“, e);

}

try {

Slog.i(TAG, ”Headset Observer“);

// Listen for wired headset changes

headset = new HeadsetObserver(context);

} catch(Throwable e){

Slog.e(TAG, ”Failure starting HeadsetObserver“, e);

}

try {

Slog.i(TAG, ”Dock Observer“);

// Listen for dock station changes

dock = new DockObserver(context, power);

} catch(Throwable e){

Slog.e(TAG, ”Failure starting DockObserver“, e);

}

try {

Slog.i(TAG, ”USB Service“);

// Listen for USB changes

usb = new UsbService(context);

ServiceManager.addService(Context.USB_SERVICE, usb);

} catch(Throwable e){

Slog.e(TAG, ”Failure starting UsbService“, e);

}

try {

Slog.i(TAG, ”UI Mode Manager Service");

第二篇:Android 应用调查.doc

Android 应用调查:

分类:系统工具,社交,音乐视频,浏览器输入法,交通地图,购物娱乐,阅读资讯,拍照,词典,主题桌面,健康,通信,办公,理财,其它

1.系统工具: 360卫士,QQ手机管家,墨迹天气,ES文件浏览器,手机LED灯,Go锁屏,海桌HiaPa,金山电池医生,LEB安全大师,语音360…

2.社交:手机QQ,微博,微信,世纪佳缘,人人,飞信,米聊,开心网,腾讯微

博,手机旺旺,MSN,朋友网,手机百合,豆瓣,facebook….3.音乐视频:天天动听,奇艺,手机电视,Adobe Flash,酷狗音乐播放器,酷我音

乐2012,PPS播放器,手机暴风影音,QQ音乐,QQ影音,QvodPlay,优酷,土豆,腾讯视频,youtube,芒果TV….4.浏览器输入法: UC,手机浏览器,搜狗输入法,百度输入法,QQ输入法,Google

输入法,百度浏览器...

5.交通地图:Google地图,百度地图,盛名时刻表,ATM位置通,深圳地铁…

6.购物娱乐:京东,美团,当当,手机支付宝,赶集,拉手,58同城,凡客,QQ

财付通,乐淘….7.阅读资讯:QQ手机阅读,凤凰阅读,新浪阅读,网易阅读,中关村在线,掌上

书库,百度文库….8.拍照:360手机摄影,9.词典:有道,新华,金山,Google翻译,同声翻译,天天英语….10.主题桌面:360,go桌面,91手机桌面,Go锁屏,Go主题…

11.健康:通信,办公,理财,其它

Android 应用开发需求: 95%都是公司内部产品上面,需要手机客户端支持,

第三篇:struts2源代码分析(个人觉得非常经典)

本章讲述Struts2的工作原理。

读者如果曾经学习过Struts1.x或者有过Struts1.x的开发经验,那么千万不要想当然地以为这一章可以跳过。实际上Struts1.x与Struts2并无我们想象的血缘关系。虽然Struts2的开发小组极力保留Struts1.x的习惯,但因为Struts2的核心设计完全改变,从思想到设计到工作流程,都有了很大的不同。

Struts2是Struts社区和WebWork社区的共同成果,我们甚至可以说,Struts2是WebWork的升级版,他采用的正是WebWork的核心,所以,Struts2并不是一个不成熟的产品,相反,构建在WebWork基础之上的Struts2是一个运行稳定、性能优异、设计成熟的WEB框架。

本章主要对Struts的源代码进行分析,因为Struts2与WebWork的关系如此密不可分,因此,读者需要下载xwork的源代码,访问http://文件,则通过过滤器链继续往下传送,直到到达请求的资源为止。

如果getMapping()方法返回有效的ActionMapping对象,则被认为正在请求某个Action,将调用Dispatcher.serviceAction(request, response, servletContext, mapping)方法,该方法是处理Action的关键所在。上述过程的源代码如清单15所示。

代码清单15:FilterDispatcher.doFilter()方法

publicvoid doFilter(ServletRequest req, ServletResponse res, FilterChain chain)throws IOException, ServletException {

HttpServletRequest request =(HttpServletRequest)req;

HttpServletResponse response =(HttpServletResponse)res;

ServletContext servletContext = getServletContext();

String timerKey = “FilterDispatcher_doFilter: ”;

try {

UtilTimerStack.push(timerKey);

request = prepareDispatcherAndWrapRequest(request, response);//重新包装request

ActionMapping mapping;

try {

mapping = actionMapper.getMapping(request, dispatcher.getConfigurationManager());//得到存储Action信息的ActionMapping对象

} catch(Exception ex){

……(省略部分代码)

return;

}

if(mapping == null){//如果mapping为null,则认为不是请求Action资源

String resourcePath = RequestUtils.getServletPath(request);

if(“".equals(resourcePath)&& null!= request.getPathInfo()){

resourcePath = request.getPathInfo();

}

{

ngth());

//如果请求的资源以/struts开头,则当作静态资源处理

if(serveStatic && resourcePath.startsWith(”/struts“))

String name = resourcePath.substring(”/struts“.le

findStaticResource(name, request, response);} else {

//否则,过滤器链继续往下传递

chain.doFilter(request, response);}

// The framework did its job here

return;

}

//如果请求的资源是Action,则调用serviceAction方法。

dispatcher.serviceAction(request, response, servletContext, mapping);

} finally {

try {

ActionContextCleanUp.cleanUp(req);

}

} finally {

UtilTimerStack.pop(timerKey);

} }

这段代码的活动图如图18所示:

(图18)

在Dispatcher.serviceAction()方法中,先加载Struts2的配置文件,如果没有人为配置,则默认加载struts-default.xml、struts-plugin.xml和struts.xml,并且将配置信息保存在形如com.opensymphony.xwork2.config.entities.XxxxConfig的类中。

类com.opensymphony.xwork2.config.providers.XmlConfigurationProvider负责配置文件的读取和解析,addAction()方法负责读取标签,并将数据保存在ActionConfig中;addResultTypes()方法负责将标签转化为ResultTypeConfig对象;loadInterceptors()方法负责将标签转化为InterceptorConfig对象;loadInterceptorStack()方法负责将标签转化为InterceptorStackConfig对象;loadInterceptorStacks()方法负责将标签转化成InterceptorStackConfig对象。而上面的方法最终会被addPackage()方法调用,将所读取到的数据汇集到PackageConfig对象中,细节请参考代码清单16。

代码清单16:XmlConfigurationProvider.addPackage()方法

protected PackageConfig addPackage(Element packageElement)throws ConfigurationException {

PackageConfig newPackage = buildPackageContext(packageElement);

age

if(newPackage.isNeedsRefresh()){

return newPackage;} if(LOG.isDebugEnabled()){

LOG.debug(”Loaded “ + newPackage);} // add result types(and default result)to this package addResultTypes(newPackage, packageElement);// load the interceptors and interceptor stacks for this packloadInterceptors(newPackage, packageElement);// load the default interceptor reference for this package loadDefaultInterceptorRef(newPackage, packageElement);// load the default class ref for this package loadDefaultClassRef(newPackage, packageElement);// load the global result list for this package loadGlobalResults(newPackage, packageElement);// load the global exception handler list for this package

loadGlobalExceptionMappings(newPackage, packageElement);

// get actions

NodeList actionList = packageElement.getElementsByTagName(”action“);

for(int i = 0;i < actionList.getLength();i++){

Element actionElement =(Element)actionList.item(i);

addAction(actionElement, newPackage);

}

// load the default action reference for this package

loadDefaultActionRef(newPackage, packageElement);

configuration.addPackageConfig(newPackage.getName(), newPackage);

return newPackage;

}

活动图如图19所示:

(图19)

配置信息加载完成后,创建一个Action的代理对象——ActionProxy引用,实际上对Action的调用正是通过ActionProxy实现的,而ActionProxy又由ActionProxyFactory创建,ActionProxyFactory是创建ActionProxy的工厂。

注:ActionProxy和ActionProxyFactory都是接口,他们的默认实现类分别是DefaultActionProxy和DefaultActionProxyFactory,位于com.opensymphony.xwork2包下。

在这里,我们绝对有必要介绍一下com.opensymphony.xwork2.DefaultActionInvocation类,该类是对ActionInvocation接口的默认实现,负责Action和截拦器的执行。

在DefaultActionInvocation类中,定义了invoke()方法,该方法实现了截拦器的递归调用和执行Action的execute()方法。其中,递归调用截拦器的代码如清单17所示:

代码清单17:调用截拦器,DefaultActionInvocation.invoke()方法的部分代码

if(interceptors.hasNext()){

//从截拦器集合中取出当前的截拦器

final InterceptorMapping interceptor =(InterceptorMapping)interceptors.next();

UtilTimerStack.profile(”interceptor: “+interceptor.getName(),new UtilTimerStack.ProfilingBlock(){

public String doProfiling()throws Exception {

//执行截拦器(Interceptor)接口中定义的intercept方法

resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);

returnnull;

}

});

}

从代码中似乎看不到截拦器的递归调用,其实是否递归完全取决于程序员对程序的控制,先来看一下Interceptor接口的定义:

代码清单18:Interceptor.java publicinterface Interceptor extends Serializable {

void destroy();

void init();

String intercept(ActionInvocation invocation)throws Exception;}

所有的截拦器必须实现intercept方法,而该方法的参数恰恰又是ActionInvocation,所以,如果在intercept方法中调用invocation.invoke(),代码清单17会再次执行,从Action的Intercepor列表中找到下一个截拦器,依此递归。下面是一个自定义截拦器示例:

代码清单19:CustomIntercepter.java publicclass CustomIntercepter extends AbstractInterceptor {

@Override

public String intercept(ActionInvocation actionInvocation)throws Exception

} { actionInvocation.invoke();return”李赞红“;}

截拦器的调用活动图如图20所示:

(图20)

如果截拦器全部执行完毕,则调用invokeActionOnly()方法执行Action,invokeActionOnly()方法基本没做什么工作,只调用了invokeAction()方法。

为了执行Action,必须先创建该对象,该工作在DefaultActionInvocation的构造方法中调用init()方法早早完成。调用过程是:DefaultActionInvocation()->init()->createAction()。创建Action的代码如下:

代码清单20:DefaultActionInvocation.createAction()方法

protectedvoid createAction(Map contextMap){

try {

action = objectFactory.buildAction(proxy.getActionName(), proxy.getNamespace(), proxy.getConfig(), contextMap);

} catch(InstantiationException e){

……异常代码省略

}

}

Action创建好后,轮到invokeAction()大显身手了,该方法比较长,但关键语句实在很少,用心点看不会很难。

代码清单20:DefaultActionInvocation.invokeAction()方法

protected String invokeAction(Object action, ActionConfig actionConfig)throws Exception {

//获取Action中定义的execute()方法名称,实际上该方法是可以随便定义的

String methodName = proxy.getMethod();

String timerKey = ”invokeAction: “+proxy.getActionName();

try {

UtilTimerStack.push(timerKey);

Method method;

try {

//将方法名转化成Method对象

method = getAction().getClass().getMethod(methodName, new Class[0]);

} catch(NoSuchMethodException e){

// hmm--OK, try doXxx instead

try {

//如果Method出错,则尝试在方法名前加do,再转成Method对象

String altMethodName = ”do“ + methodName.substring(0, 1).toUpperCase()+ methodName.substring(1);

method = getAction().getClass().getMethod(altMethodName, new Class[0]);

} catch(NoSuchMethodException e1){

// throw the original one

throw e;

}

}

//执行方法

[0]);

}

Object methodResult = method.invoke(action, new Object

//处理跳转

if(methodResult instanceof Result){

this.result =(Result)methodResult;

returnnull;

} else {

return(String)methodResult;

} } catch(NoSuchMethodException e){

……省略异常代码 } finally {

UtilTimerStack.pop(timerKey);}

刚才使用了一段插述,我们继续回到ActionProxy类。

我们说Action的调用是通过ActionProxy实现的,其实就是调用了ActionProxy.execute()方法,而该方法又调用了ActionInvocation.invoke()方法。归根到底,最后调用的是DefaultActionInvocation.invokeAction()方法。

以下是调用关系图:

其中:

Ø

ActionProxy:管理Action的生命周期,它是设置和执行Action的起始点。

Ø

ActionInvocation:在ActionProxy层之下,它表示了Action的执行状态。它持有Action实例和所有的Interceptor

以下是serviceAction()方法的定义:

代码清单21:Dispatcher.serviceAction()方法

publicvoid serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context,ActionMapping mapping)throws ServletException {

Map extraContext = createContextMap(request, response, mapping, context);

// If there was a previous value stack, then create a new copy and pass it in to be used by the new Action

ValueStack stack =(ValueStack)request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);

if(stack!= null){

extraContext.put(ActionContext.VALUE_STACK, ValueStackFactory.getFactory().createValueStack(stack));

}

String timerKey = ”Handling request from Dispatcher“;

try {

UtilTimerStack.push(timerKey);

String namespace = mapping.getNamespace();

String name = mapping.getName();

String method = mapping.getMethod();

Configuration config = configurationManager.getConfiguration();

ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(namespace, name, extraContext, true, false);

proxy.setMethod(method);

request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());

// if the ActionMapping says to go straight to a result, do it!

if(mapping.getResult()!= null){

Result result = mapping.getResult();

result.execute(proxy.getInvocation());

} else {

proxy.execute();

}

// If there was a previous value stack then set it back onto the request

if(stack!= null){

request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack);

}

} catch(ConfigurationException e){

LOG.error(”Could not find action or result", e);

sendError(request, response, context, HttpServletResponse.SC_NOT_FOUND, e);

} catch(Exception e){

thrownew ServletException(e);

} finally {

UtilTimerStack.pop(timerKey);

}

}

最后,通过Result完成页面的跳转。

3.4 本小节总结

总体来讲,Struts2的工作机制比Struts1.x要复杂很多,但我们不得不佩服Struts和WebWork开发小组的功底,代码如此优雅,甚至能够感受看到两个开发小组心神相通的默契。两个字:佩服。

以下是Struts2运行时调用方法的顺序图:

(图21)

四、总结

阅读源代码是一件非常辛苦的事,对读者本身的要求也很高,一方面要有扎实的功底,另一方面要有超强的耐力和恒心。本章目的就是希望能帮助读者理清一条思路,在必要的地方作出简单的解释,达到事半功倍的效果。

当然,笔者不可能为读者解释所有类,这也不是我的初衷。Struts2+xwork一共有700余类,除了为读者做到现在的这些,已无法再做更多的事情。读者可以到Struts官方网站下载帮助文档,慢慢阅读和理解,相信会受益颇丰。

本章并不适合java语言初学者或者对java博大精深的思想理解不深的读者阅读,这其中涉及到太多的术语和类的使用,特别不要去钻牛角尖,容易使自信心受损。基本搞清楚Struts2的使用之后,再回过头来阅读本章,对一些知识点和思想也许会有更深的体会。

如果读者的java功底比较浑厚,而且对Struts2充满兴趣,但又没太多时间研究,不妨仔细阅读本章,再对照Struts的源代码,希望对您有所帮助。

第四篇:调查分析

1)植被数量多,种类较丰富,但缺少大乔木.初到学校的学生,对校园绿化是很容易满意的,却不能长久关注,是学校在植物更新等方面做的还不够。与15题呼应

2)颜色是大多数人对于事物,特别是景观的第一感受(景观设计中应注重季相设计),而随着生活质量的日益提高,音乐和植物在景观布置中也更加受到重视(可以作声景观)。气味的设计容易被人忽略,但一旦出现就会成为人们接近或离开某个地方的最主要因素。

3)夏天花多反而让人觉得乱,没有头绪,秋天,校园里花楸、卫矛成主景(其他季节景观设计应加强)。

4)针对农业院校而设立的题型(现在校园作物收获后,大片空地荒废,影响景观)(可在外围适当种灌木围合、遮挡)

5)说明人们更喜欢新鲜奇特的东西。与10、12题呼应

6)通过这题说明了在进行设计时因充分考虑其功能性。车辆的高分贝噪声对学生学习的影响很大,在设计中应尽量避免学校周围的交通干道,校园内车辆应慢行。与8题呼应

7)有些虫子会使草地更显自然,本题的选项会反映出一个人的个性,说明性格对景观的使用也是有影响的。

8)车辆、人行和高分贝的音乐噪音对学生学习的影响很大,在设计中应尽量避免学校周围的交通干道,校园内车辆应慢行。在学生公寓附近的道路做到人流分散。增加建筑的隔音效果的同时进行噪音污染的教育。(舒缓的音乐,鸟鸣等可以使人放松、安神,可在休闲广场适当应用创造声景)

9)选择会依心情而定,可在密林中空出一片草地,可以满足不同需要的人,也可使选②(私密性强)的人豁然开朗。

10)符合大学生自由、开放、热情、喜欢不受拘束的天性。

11)与私密性、对个人空间的要求和东方人的性格有关,还有就是东西方文化的差异。

12)功能也是选择树种的一个重要方面。

13)人们都有好奇的天性,看到有围观,自然会围上去,只是希望美景不会让人失望。还要能做到能吸引游人,引人驻足的景观十分重要(要具有生态效应)。

14)绿色是自然的象征,是植物的主色调(占地面积大)。不同的颜色带给人不同的心情,适当运用各种颜色,创造带给游客不同感觉的景。

15)一方面:大学校园在环境保护方面相对完善,基本满足了人们的的需要。

另一方面:在国内,人们在环境保护方面意识还不够强烈,了解较少,不够全面。

第五篇:厦门手机开发培训Android手机模式分析

厦门手机开发培训Android手机模式分析

第一部分其实游戏就是厦门博看文思让状态机不断的让Canvas在View上画你想要的东西。这个状态机包括内部的执行,还包括外部的输入。

Android开发的MVC模式

1,通过View和SurfaceView来显示界面的视图。(处理界面与用户的交互事件,如,触笔点击,用户按键等。可通过View类的onKeyDown,onKeyUp,onTouchEvent等)。

2,用Activity来控制游戏的整体结构。

3,设计一个逻辑类,用来处理逻辑运算。

Android中任何一个View类都只有重写onDraw方法来实现界面显示。

Android中提供了

onKeyUp,onKeyDown,onKeyMultiple,onKeyPreIme,onTouchEvent,onTrackballEvent等方法。可以用来处理游戏中的事件消息。所以继承View时,需要重载这些方法。Android中提供了invalidate来刷新界面,但invalidate不能直接在线程中调用,违背单线程模型。

因此Android中最常用的方法是利用Handler来时更新UI界面。

第一部分View类

每个View类都有一个绘画的画布,在游戏中可以自定义视图View,任何一个View类都只需要重写onDraw方法来实现界面显示,可以是3D,也可以是文本。

游戏的核心就是不断的绘图和刷新,图我们可以通过onDraw方法绘制,刷新

Android中可以用invalidate方法来刷新界面,注意:invalidate不能直接在线程中调用,因其违背了

违背单线程模型。因此Android中最常用的方法是厦门博看文思利用Handler来时更新UI界面。下面这个例子中包含了两个刷新方法。

下载Android系统启动源代码调查分析word格式文档
下载Android系统启动源代码调查分析.doc
将本文档下载到自己电脑,方便修改和收藏,请勿使用迅雷等下载。
点此处下载文档

文档为doc格式


声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:645879355@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。

相关范文推荐

    满意度调查分析

    土木工程学院指导教师满意度调查分析 2011年 为加强土木工程学院指导教师管理工作,学生科于2011年3-5月由土木工程学院425名同学对本院系的16位指导老师的工作进行工作态度、......

    调查与分析

    消费者行为学 第一章 绪论 1.消费者行为 2.消费者 3.经济人理论 4.信息的搜寻 5.购买 险 25.物理风险1. 2. 简述感觉义和意义。 简述决定知觉选择性的机制。 1.消费者需要 2......

    调查问卷情况分析

    调查问卷情况分析 根据调研安排,由市委组织部牵头开展调查问卷工作,现初步分析如下: 一、问卷基本情况 问卷从干部精神状态、干事创业现状、存在问题、主要原因和努力方向五个......

    刊物调查分析★

    第二阶段刊物信息收集调查分析报告一、调查目的: 在东莞市内搜索各类非公开发售的杂志,收集其出版周期、行业类型、主办单位信息等,总体了解市场上各类杂志的分布情况,为我局的......

    调查分析报告

    大学生生活费调查报告一、引言 当我们远离父母在外求学之时,生活学习的各个方面都需要自己管理,如何合理的消费成为了很多同学最关心的问题。作为大学生,我们是社会消费者中的......

    中国书店调查分析

    江龙中国书店网络营销市场调查分析书中国书店网络营销市场调查分析书这次市场调查总共向社会发放调查问卷50份,采取街头采访的调查方式,主要针对网络经营的一些市场动向和市场......

    调查分析格式(5篇材料)

    调查情况分析 一、基本情况(基础数据、调查的简单介绍) 二、开展调查 如:(一)加强组织领导(二)制定工作方案(三)精心组织(四)强化调查培训(五)加强督查指导.... 三、数据分析 如:(一)农村劳......

    中期调查分析

    小学低年级字理识字教学的研究 《小学低年级字理识字教学的研究》中期学生调查问卷分析 包头市土右旗东胜街小学课题组 一、前期与中期问卷对比分析 (一)与前测对比 1.你喜欢字......