參考:http://blog.csdn.net/xingyu19871124/article/details/7750189
http://blog.csdn.net/BonderWu/article/details/5814278
http://blog.chinaunix.net/uid-2630593-id-3307176.html
http://zhidao.baidu.com/question/388864295.html
等
注:把本文內容復制到source insight中查看效果較好
線程與進程:子進程和父進程有不同的代碼和數據空間,而多個線程則共享數據空間,每個線程有自己的執行堆棧和程序計數器為其執行上下文。
Handler與線程: 其實Handler並不是開辟新線程的概念,Android主要的考慮到更新界面的問題,一般情況下,更新界面(Activity)都是在主線程中更新的,
這樣就遇到了一個問題,比方說:在下載文件時候我們需要進度條顯示下載進度,界面需要更新(數據是不斷變的,也就是下載的大小是不斷變的,要是直接
在主線程中更新,就會造成程序的堵塞,程序很容易崩潰,通常這樣聯網耗時的工作需要開辟另外一個線程的,這樣就不會影響主程序了),好了,到這里聯
網操作一般都需要開辟新線程了吧。
接下來就來說Handler了,剛剛我說了Handler不是開辟新線程,在我看來,Handler更像是主線程的秘書,是一個觸發器,負責管理從子線程中得到更新的數據,
然后在主線程中更新界面。簡單說下進度條的那個: 下載了多少的數據都是在子線程中得到的,在子線程中通過Handler的sendMessage()方法發送得到的下載
的數據,當你調用了sendMessage方法后,Handler就會回調(也就是自動調用)Handler中的 HandlerMessage方法。
啟動線程:Android啟動線程和JAVA一樣有兩種方式,一種是直接Thread類的start方法,也就是一般寫一個自己的類來繼承Thread 類。
另外一種方式其實和這個差不多啊! 那就是Runnable接口,然后把Runnable的子類對象傳遞給Thread類再創建Thread對象.總之都是需要創建Thread對象,
然后調用Thread類的start方法啟動線程。區別就是,一個是直接創建Thread對象,另外一個是需要implement了Runnable接口對象作為創建Thread對象的參數.
Runnable其實我們稱為線程任務。
第一種方式一般是這樣用:
Class MyThread extends Thread{
public void run(){
//你要實現的代碼
}
}
在主線程中啟動這個線程:
public class Test{
public static void main(String[] args){
new MyThread().start();//啟動了我們的線程了
}
}
2,第二種方式一般是這樣用:
public class MyRunnable implements Runnable{
public void run(){
//你需要實現的代碼
}
}
在主線程中啟動這個線程:
public class Test{
public static void main(String[] args){
Thread t=new Thread(new MyRunnable());//這里比第一種創建線程對象多了個任務對象
t.start();
}
}
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
cpp:
LOGD("dyyr - log %s, %s", __FILE__, __FUNCTION__);
打開camera/喚醒camera 大致流程途徑源文件:
Camera.java onCreate() log1
開啟一個新線程,在此線程中open camera
mCameraOpenThread的run()
log2
運行構造函數中的run()
是上述兩種開啟線程方法中的第一種
Then do something about rotation and else.
在onCreate()中以mCameraOpenThread.join();這句等待該線程完成它的任務
再開啟預覽線程mCameraPreviewThread.start();
mCameraPreviewThread的run()
1872 log14
startPreview()
log14.5
mCameraDevice是在log4的位置定義的,是log5返回的一個android.hardware.Camera對象
(因為log5源文件第一句:package android.hardware;)
這個對象的startPreview方法聲明在log5下面。481行
而它在log15定義。
Util.java openCamera() log3
CameraHolder.java open() log4
Applications
---------------------------------------------------------------------------------------------------------------------------
Camera.java open() log5
Framework
---------------------------------------------------------------------------------------------------------------------------
android_hardware_camera.cpp
android_hardware_Camera_native_setup()
log6
android_hardware_Camera_startPreview()
log15
Camera.cpp connect() log7
startPreview() log16
CameraService.cpp connect() log8 IServiceManager.cpp ServiceManager.java(comfirmed)
log8.1
log8.2
Client() log8.3~8.8
怎么到下面的log9?
startPreview() log17
startCameraMode() log18
startPreviewMode()log19
JNI
---------------------------------------------------------------------------------------------------------------------------
進入camera之前(開機時),camera初始化
CameraHardwareDevice.cpp Initialize() log'1
ALCameraFactory.cpp device_open() log9 (name=0) V4L2CameraDevice.cpp Initialize() log'2
cameraDeviceOpen() log10
CameraHardware.cpp connectCamera() log11 V4L2Camera.cpp Initialize() log'3
startPreview() log20
doStartPreview() log21
V4L2CameraDevice.cpp connectDevice() log12 V4L2Camera.h WorkerThread() log'4 上述兩種開啟線程方法中的第一種,但並沒有run(),
所以還沒有真正開啟線程,初始化了一個指針V4L2Camera* camera_dev
openCameraDev() log13
在這個最終打開設備文件的函數中,open()得到文件描述符后,
用iotrl()函數做了一些配置然后返回了
PreviewWindow.cpp startPreview() log22
onNextFrameAvailableHW() log23
通過perform向mPreviewWindow窗體發送消息
打開camera並開啟預覽的流程跟到這里。
camera.cfg
HAL
---------------------------------------------------------------------------------------------------------------------------
gc0308.c
Sys_config1.fex
Kernel
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
cpp:
LOGD("dyyr - log %s, %s", __FILE__, __FUNCTION__);
Camera.java
1117 public void onCreate(Bundle icicle) { //打開
......
mCameraOpenThread.start(); // 1097
......
}
1097 Thread mCameraOpenThread = new Thread(new Runnable() {
public void run() {
try {
mCameraDevice = Util.openCamera(Camera.this, mCameraId); //Util.java 267
}
.......
}
}
1532 protected void doOnResume() { //喚醒
......
Util.openCamera(this, mCameraId); //Util.java 267
......
}
1836 private void startPreview() {
......
if (mCameraPreviewThread != null) {
synchronized (mCameraPreviewThread) {
mCameraPreviewThread.notify(); //開啟預覽線程
}
}
......
}
Util.java package/apps/.../camera
267 CameraHolder.instance().open(cameraId);
CameraHolder.java package/apps/.../camera
131 android.hardware.Camera.open(cameraId); //無法自動定位,frameworks/base/core/java/android/hardware/Camera.java 264 open()
packages/apps/camera/src/com/android/camera/ --------> Camera.apk
Applications
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Camera.java frameworks/base/core/java/android/hardware/Camera.java --------> framework.jar
264 public static Camera open(int cameraId) {
return new Camera(cameraId);
} //open函數是一個靜態方法,構造一個Camera對象
285 Camera(int cameraId) { //構造函數
mShutterCallback = null;
mRawImageCallback = null;
mJpegCallback = null;
mPreviewCallback = null;
mPostviewCallback = null;
mZoomListener = null;
Looper looper;
if ((looper = Looper.myLooper()) != null) {
mEventHandler = new EventHandler(this, looper);
} else if ((looper = Looper.getMainLooper()) != null) {
mEventHandler = new EventHandler(this, looper);
} else {
mEventHandler = null;
}
native_setup(new WeakReference<Camera>(this), cameraId); //310
}
310 private native final void native_setup(Object camera_this, int cameraId); 其對應於android_hardware_Camera.cpp的android_hardware_Camera_native_setup方法,為什么????
貌似是有函數會去按照camMethods數組匹配
Frameworks
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
android_hardware_camera.cpp frameworks/base/core/jni
458 // connect to camera service
static void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
jobject weak_this, jint cameraId)
{
sp<Camera> camera = Camera::connect(cameraId); //無法自動定位. Camera.cpp 128
//Camera C/S架構的客戶端調用connect函數向服務器發送連接請求,
//這個Camera類的聲明在Camera.h (android4.0\frameworks\base\include\camera)
if (camera == NULL) {
jniThrowRuntimeException(env, "Fail to connect to camera service");
return;
}
// make sure camera hardware is alive
if (camera->getStatus() != NO_ERROR) {
jniThrowRuntimeException(env, "Camera initialization failed");
return;
}
jclass clazz = env->GetObjectClass(thiz);
if (clazz == NULL) {
jniThrowRuntimeException(env, "Can't find android/hardware/Camera");
return;
}
// We use a weak reference so the Camera object can be garbage collected.
// The reference is only used as a proxy for callbacks.
sp<JNICameraContext> context = new JNICameraContext(env, weak_this, clazz
, camera);
context->incStrong(thiz);
camera->setListener(context);
// save context in opaque field
env->SetIntField(thiz, fields.context, (int)context.get());
}
Camera.cpp frameworks/base/libs/camera
128 sp<Camera> Camera::connect(int cameraId)
{
LOGV("connect");
sp<Camera> c = new Camera();
const sp<ICameraService>& cs = getCameraService(); //獲取一個Camera服務實例,本源文件40行
if (cs != 0) {
c->mCamera = cs->connect(c, cameraId); //然后執行服務端的connect()函數,並返回一個ICamera對象賦值給Camera 的mCamera,
//CameraService.cpp 185~254
}
if (c->mCamera != 0) {
c->mCamera->asBinder()->linkToDeath(c);
c->mStatus = NO_ERROR;
} else {
c.clear();
}
return c;
}
40 // establish binder interface to camera service
const sp<ICameraService>& Camera::getCameraService()
{
Mutex::Autolock _l(mLock);
if (mCameraService.get() == 0) {
sp<IServiceManager> sm = defaultServiceManager(); //無法自動定位,調用的是IServiceManager.cpp(frameworks/base/libs/binder) 34
sp<IBinder> binder;
do {
binder = sm->getService(String16("media.camera")); //無法自動定位,搜索符號getService,定位到ServiceManager.java 49
if (binder != 0)
break;
LOGW("CameraService not published, waiting...");
usleep(500000); // 0.5 s
} while(true);
if (mDeathNotifier == NULL) {
mDeathNotifier = new DeathNotifier();
}
binder->linkToDeath(mDeathNotifier);
mCameraService = interface_cast<ICameraService>(binder); //mCameraService是一個ICamerService類型,
//更加具體具體一點來講應該是BpCameraService,因為在這個類中實現了ICameraService的方法。
}
LOGE_IF(mCameraService==0, "no CameraService!?");
return mCameraService;
}
IServiceManager.cpp frameworks/base/libs/binder
34 sp<IServiceManager> defaultServiceManager()
{
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
if (gDefaultServiceManager == NULL) {
gDefaultServiceManager = interface_cast<IServiceManager>( //得到上面要的sm,它的類型是"sp<IServiceManager>",
//sp<T>是android的智能指針,它持有一個T類實例,並負責在必要時釋放此實例
ProcessState::self()->getContextObject(NULL));
}
}
return gDefaultServiceManager;
}
我們有必要關注一下interface_cast,通過代碼跟蹤:看到它的實現
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}
通過模板替換就是:
inline sp< IServiceManager > interface_cast(const sp<IBinder>& obj)
{
return IServiceManager::asInterface(obj);
}
看來asInterface是IServiceManager的一個成員函數,我們打開IServiceManager.cpp/
h文件,我們並沒有發現該函數,那它到底在哪兒呢,仔細觀察IServiceManager.cpp
,發現里面有個IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
在IServiceManager.h里面發現了DECLARE_META_INTERFACE(ServiceManager);
通過跟蹤這兩個宏發現DECLARE_META_INTERFACE聲明了一個變量和兩個函數...
interface_cast<IServiceManager>實際上返回了一個BpServiceManager,在創建一個BpServiceManager時,有些細節還是需要注意:...
ServiceManager.java frameworks/base/core/java/android/os
49 public static IBinder getService(String name) {
Log.d(TAG, "dyyr - getService");
try {
IBinder service = sCache.get(name); //sCache是個Hashmap<String,IBinder>,用參數name:"media.camera"get這個IBinder,
//那么,這個media.camera是源代碼里配置好的還是開機后添加進去的?何時添加的?
if (service != null) {
return service;
} else {
return getIServiceManager().getService(name);
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
CameraService.cpp frameworks/base/services/camera/libcameraservice
185 sp<ICamera> CameraService::connect( //服務端connect()
const sp<ICameraClient>& cameraClient, int cameraId) {
LOGE("dyyr - CameraService.cpp connect");
int callingPid = getCallingPid();
sp<CameraHardwareInterface> hardware = NULL; //先實例化Camera Hal接口 hardware,
......
246 if (hardware->initialize(&mModule->common) != OK) { //hardware調用initialize()進入HAL層打開Camear驅動, CameraHardwareDevice.cpp 52
hardware.clear();
return NULL;
}
client = new Client(this, cameraClient, hardware, cameraId, info.facing,
callingPid);
mClient[cameraId] = client;
LOG1("CameraService::connect X");
return client; //返回的其實是它內部類client的一個實例。
}
//Camera系統使用的是Server-Client機制,Service和Client位於不同的進程中,進程間使用Binder機制進行通信,
//Service端實際實現相機相關的操作,Client端通過Binder接口調用Service對應的操作。
//如下圖所示
android_hardware_camera.cpp fremework/base/core/jni --------> libandroid_runtime.so
|
|
------ | --------------------------
| --------- --------- |
| | Client | | Service |-----------Binder IPC---------
| --------- --------- | |
| libui.so | |
----------------------------------- |
------
|
Camera服務 |
CameraService.cpp等 frameworks/base/camera/libcameraservice/ --------> libcameraservice.so <------------------------------------
( UI 庫 frameworks/base/libs/ui/camera --------> libcamera_client.so )
JNI
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CameraHardwareDevice.cpp device/softwinner/common/hardware/camera/
52 status_t CameraHardwareDevice::Initialize()
{
F_LOG;
// instance V4L2CameraDevice object
mV4L2CameraDevice = new V4L2CameraDevice(this, mCameraID);
if (mV4L2CameraDevice == NULL)
{
LOGE("Failed to create V4L2Camera instance");
return NO_MEMORY;
}
status_t res = mV4L2CameraDevice->Initialize(); //V4L2CameraDevice.cpp 71
......
}
V4L2CameraDevice.cpp device/softwinner/common/hardware/camera/
71 status_t V4L2CameraDevice::Initialize()
{
F_LOG;
return V4L2Camera::Initialize(); //V4L2Camera.cpp 66
}
V4L2Camera.cpp device/softwinner/common/hardware/camera/
66 status_t V4L2Camera::Initialize()
{
LOGE("dyyr - %s, %s", __FILE__, __FUNCTION__);
F_LOG;
if (isInitialized()) {
LOGW("%s: V4L2Camera device is already initialized: mState = %d",
__FUNCTION__, mState);
return NO_ERROR;
}
/* Instantiate worker thread object. */
mWorkerThread = new WorkerThread(this); //V4L2Camera.h 325
if (getWorkerThread() == NULL) {
LOGE("%s: Unable to instantiate worker thread object", __FUNCTION__);
return ENOMEM;
}
mState = ECDS_INITIALIZED;
return NO_ERROR;
}
V4L2Camera.h device/softwinner/common/hardware/camera/
325 inline explicit WorkerThread(V4L2Camera* camera_dev)
: Thread(true), // Callbacks may involve Java calls. //頂層打開/喚醒Camera的流程跟到這里---------------------------未完待續
mCameraDevice(camera_dev),
mThreadControl(-1),
mControlFD(-1)
{
}
------------------------------------------------------------------
下面是camera的HAL層open底層驅動的方法,沒有使用傳統的這一句:module->methods->open(module, mName.string(),(hw_device_t **)&mDevice),而走的是V4L2途徑:
HALCameraFactory.cpp device/softwinner/common/hardware/camera/
201 struct hw_module_methods_t HALCameraFactory::mCameraModuleMethods = {
open: HALCameraFactory::device_open // 160
};
160 int HALCameraFactory::device_open(const hw_module_t* module,
const char* name,
hw_device_t** device)
{
F_LOG;
/*
* Simply verify the parameters, and dispatch the call inside the //只需確定參數,並調用HALCamera 實例.
* HALCameraFactory instance.
*/
......
return gEmulatedCameraFactory.cameraDeviceOpen(atoi(name), device); // 118
}
118 int HALCameraFactory::cameraDeviceOpen(int camera_id, hw_device_t** device)
{
LOGV("%s: id = %d", __FUNCTION__, camera_id);
......
return mHardwareCameras[camera_id]->connectCamera(device); //CameraHardware.cpp 435
}
CameraHardware.cpp device/softwinner/common/hardware/camera/
435 status_t CameraHardware::connectCamera(hw_device_t** device)
{
......
if (camera_dev != NULL) {
/* Connect to the camera device. */
res = getCameraDevice()->connectDevice(); //V4L2CameraDevice 83
if (res == NO_ERROR) {
*device = &common;
}
}
return -res;
}
V4L2CameraDevice.cpp device/softwinner/common/hardware/camera/
83 status_t V4L2CameraDevice::connectDevice()
{
......
// open v4l2 camera device
int ret = openCameraDev(); //448
if (ret != OK)
{
return ret;
}
ret = cedarx_hardware_init(2);// CEDARX_HARDWARE_MODE_VIDEO
......
}
448 int V4L2CameraDevice::openCameraDev()
{
// open V4L2 device
Log.d(TAG, "dyyr - " + __FILE__ + ", " + __FUNCTION__);
mCamFd = open(mDeviceName, O_RDWR | O_NONBLOCK, 0); //至此完成打開底層設備全過程
if (mCamFd == -1)
{
LOGE("ERROR opening V4L interface: %s", strerror(errno));
return -1;
}
struct v4l2_input inp;
inp.index = mDeviceID;
if (-1 == ioctl (mCamFd, VIDIOC_S_INPUT, &inp))
{
LOGE("VIDIOC_S_INPUT error!\n");
return -1;
}
......
}
--------------------------------------------------------------------------
HAL層的配置文件camera.cfg device/softwinner/Dimond_97HD/camera.cfg, 讀取配置: CCameraConfig.cpp, xxx()
下面是讀取配置信息的一個例子:
CameraHardware.cpp device/softwinner/common/hardware/camera/
105 status_t CameraHardware::Initialize()
{
F_LOG;
if (mCameraConfig == NULL)
{
return UNKNOWN_ERROR;
}
initDefaultParameters(); //145
return NO_ERROR;
}
145 void CameraHardware::initDefaultParameters()
{
......
if (mCameraConfig->cameraFacing() == CAMERA_FACING_BACK) //根據配置信息設置XX
{
p.set(CameraHardware::FACING_KEY, CameraHardware::FACING_BACK);
LOGV("%s: camera is facing %s", __FUNCTION__, CameraHardware::FACING_BACK
);
}
else
{
p.set(CameraHardware::FACING_KEY, CameraHardware::FACING_FRONT);
LOGV("%s: camera is facing %s", __FUNCTION__, CameraHardware::
FACING_FRONT);
}
p.set(CameraHardware::ORIENTATION_KEY, 0);
......
}
HAL
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
gc0308.c drivers/media/video/sun4i_csi/device/gc0308.c
配置文件Sys_config1.fex Tools/pack/Chips/Sun4i/Configs/Crane/Dimod/Sys_config1.fex, 讀取函數: ????????
Kernel
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
