Android 5.0 Camera系統原始碼分析(2):Camera開啟流程
1. 前言
本文將分析android系統原始碼,從frameworks層到hal層,暫不涉及app層和kernel層。由於某些函式比較複雜,在貼出程式碼時會適當對其進行簡化。本文屬於自己對原始碼的總結,僅僅是貫穿程式碼流程,不會深入分析各個細節。歡迎聯絡討論,QQ:1026656828
2. app層
從apk開始,簡單列出各個入口函式
private void initCamera() { Camera mCamera = Camera.open(); Camera.Parameters mParameters = mCamera.getParameters(); mParameters.setPictureFormat(PixelFormat.JPEG); mCamera.setParameters(mParameters); mCamera.setPreviewDisplay(mSurfaceHolder); mCamera.startPreview(); mCamera.takePicture(null, null , mJpegCallback); }
3. frameworks層
這裡將重點介紹Camera.open函式,其餘函式將在後續博文分析。先來看看Camera.open函式在frameworks層的實現,程式碼路徑為: frameworks/base/core/java/android/hardware/Camera.java第5行, 通過getNumberOfCameras函式來獲取Camera的個數。從上一篇博文CameraService的啟動流程可以看出,這個資訊儲存在CameraService中。public static Camera open() { if (!isPermissionGranted()) { return null; } int numberOfCameras = getNumberOfCameras(); CameraInfo cameraInfo = new CameraInfo(); for (int i = 0; i < numberOfCameras; i++) { getCameraInfo(i, cameraInfo); if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) { return new Camera(i); } } return null; }
第10行,需重點關注,構造一個Camera物件,並將它返回給app層。
3.1 getNumberOfCameras函式分析
getNumberOfCameras函式進入到CameraService獲取Camera個數的流程如下:Camera.java呼叫的getNumberOfCameras函式是一個JNI介面,對應的函式是android_hardware_Camera.cpp裡的android_hardware_Camera_getNumberOfCameras函式
static jint android_hardware_Camera_getNumberOfCameras(JNIEnv *env, jobject thiz)
{
return Camera::getNumberOfCameras();
}
這裡只是簡單呼叫了Camera.cpp的getNumberOfCameras函式,Camera繼承了CameraBase,該函式由它實現
template <typename TCam, typename TCamTraits>
int CameraBase<TCam, TCamTraits>::getNumberOfCameras() {
const sp<ICameraService> cs = getCameraService();
return cs->getNumberOfCameras();
}
第3行, getCameraService函式用來獲取ICameraService的Bp端,程式碼實現如下const char* kCameraServiceName = "media.camera";
template <typename TCam, typename TCamTraits>
const sp<ICameraService>& CameraBase<TCam, TCamTraits>::getCameraService()
{
if (gCameraService.get() == 0) {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
binder = sm->getService(String16(kCameraServiceName));
gCameraService = interface_cast<ICameraService>(binder);
}
return gCameraService;
}
Android的Binder通訊機制
第1行, 獲取的ServiceName為"media.camera",結合上一篇博文CameraService的啟動流程可以看出Bn端的實現在CameraService.cpp
回到之前的getNumberOfCameras函式,在獲取到ICameraService的Bp端後,就可以開始和Bn端通訊了。在第4行,當呼叫cs->getNumberOfCameras函式時,將會進入CameraService.cpp的getNumberOfCameras函式
int32_t CameraService::getNumberOfCameras() {
return mNumberOfCameras;
}
程式碼很簡單,返回上一篇博文講到的,千辛萬苦從hal層拿到的資料
3.2 Camera建構函式分析
回到最開始的Camera.open函式,在第10行,將會構造一個Camera物件private int cameraInitVersion(int cameraId, int halVersion) {
......
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;
}
String packageName = ActivityThread.currentPackageName();
return native_setup(new WeakReference<Camera>(this), cameraId, halVersion, packageName);
}
private int cameraInitNormal(int cameraId) {
return cameraInitVersion(cameraId, CAMERA_HAL_API_VERSION_NORMAL_CONNECT);
}
Camera(int cameraId) {
int err = cameraInitNormal(cameraId);
......
}
第14行, native_setup同樣是個JNI介面,對應android_hardware_Camera.cpp裡的android_hardware_Camera_native_setup函式static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
jobject weak_this, jint cameraId, jint halVersion, jstring clientPackageName)
{
camera = Camera::connect(cameraId, clientName, Camera::USE_CALLING_UID);
#if 1 // defined(MTK_CAMERA_BSP_SUPPORT)
sp<JNICameraContext> context = new MtkJNICameraContext(env, weak_this, clazz, camera);
#else
sp<JNICameraContext> context = new JNICameraContext(env, weak_this, clazz, camera);
#endif
}
第4行, 呼叫了Camera.cpp的connect函式,同時返回一個Camera物件,儲存在JNICameraContext當中sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
int clientUid)
{
return CameraBaseT::connect(cameraId, clientPackageName, clientUid);
}
先來看看Camera和CameraBase的類定義
/* ---------- Camera.h ---------- */
template <>
struct CameraTraits<Camera>
{
......
static TCamConnectService fnConnectService;
};
class Camera : public CameraBase<Camera>
{
......
}
/* -------- CameraBase.h -------- */
<pre name="code" class="cpp">template <typename TCam>
struct CameraTraits {
};
template <typename TCam, typename TCamTraits = CameraTraits<TCam>>
class CameraBase
{
......
typedef CameraBase<TCam> CameraBaseT;
}
這裡使用了C++模版,其實就是呼叫CameraBase::connect函式CameraTraits<Camera>::TCamConnectService CameraTraits<Camera>::fnConnectService = &ICameraService::connect;
template <typename TCam, typename TCamTraits>
sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId,
const String16& clientPackageName,
int clientUid)
{
sp<TCam> c = new TCam(cameraId);
sp<TCamCallbacks> cl = c;
const sp<ICameraService>& cs = getCameraService();
if (cs != 0) {
TCamConnectService fnConnectService = TCamTraits::fnConnectService;
status = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid,
/*out*/ c->mCamera);
}
return c;
}
第1行, 將CameraTraits::fnConnectService賦為ICameraService::connect
第7行, 構造一個Camera物件
第10行, 獲取ICameraService的Bp端
第13行, 從上面的解釋可以看出,實際就是呼叫CameraService.cpp的connect函式
第17行, 將Camera物件返回給JNI層
status_t CameraService::connectHelperLocked(
/*out*/
sp<Client>& client,
/*in*/
const sp<ICameraClient>& cameraClient,
int cameraId,
const String16& clientPackageName,
int clientUid,
int callingPid,
int halVersion,
bool legacyMode) {
......
int deviceVersion = getDeviceVersion(cameraId, &facing);
switch(deviceVersion) {
case CAMERA_DEVICE_API_VERSION_1_0:
client = new CameraClient(this, cameraClient,
clientPackageName, cameraId,
facing, callingPid, clientUid, getpid(), legacyMode);
break;
case CAMERA_DEVICE_API_VERSION_2_0:
case CAMERA_DEVICE_API_VERSION_2_1:
case CAMERA_DEVICE_API_VERSION_3_0:
case CAMERA_DEVICE_API_VERSION_3_1:
case CAMERA_DEVICE_API_VERSION_3_2:
client = new Camera2Client(this, cameraClient,
clientPackageName, cameraId,
facing, callingPid, clientUid, getpid(), legacyMode);
break;
}
status_t status = connectFinishUnsafe(client, client->getRemote());
mClient[cameraId] = client;
}
status_t CameraService::connect(
const sp<ICameraClient>& cameraClient,
int cameraId,
const String16& clientPackageName,
int clientUid,
/*out*/
sp<ICamera>& device) {
......
sp<Client> client;
status = connectHelperLocked(/*out*/client,
cameraClient,
cameraId,
clientPackageName,
clientUid,
callingPid);
device = client;
return OK;
}
忽略細節之後connect函式就只是呼叫connectHelperLocked函式
第13行, 獲取api版本資訊,這個函式比較簡單,不細說。這裡的版本為CAMERA_DEVICE_API_VERSION_1_0
第15-30行, 根據不同的api版本選擇構造CameraClient或Camera2Client,這裡是CameraClient
第32行, 呼叫connectFinishUnsafe函式,實現如下status_t CameraService::connectFinishUnsafe(const sp<BasicClient>& client,
const sp<IBinder>& remoteCallback) {
status_t status = client->initialize(mModule);
}
這裡的client就是上一個函式的CameraClient,mModule就是在上一篇博文CameraService的啟動流程裡提到的hal層的介面status_t CameraClient::initialize(camera_module_t *module) {
mHardware = new CameraHardwareInterface(camera_device_name);
res = mHardware->initialize(&module->common);
mHardware->setCallbacks(notifyCallback,
dataCallback,
dataCallbackTimestamp,
(void *)(uintptr_t)mCameraId);
return OK;
}
構造一個CameraHardwareInterface物件,並呼叫它的initalize函式,直接看initalize函式status_t initialize(hw_module_t *module)
{
module->methods->open(module, mName.string(), (hw_device_t **)&mDevice)
initHalPreviewWindow();
}
第4行, 從這裡進入到了hal層,hal層主要對Camera硬體進行初始化,並將操作集儲存在mDevice當中4. hal層-基於MTK平臺
hal層對Camera硬體進行初始化以及返回Device操作集的流程如下
4.1 open函式分析
這裡再看一次module的定義
static
hw_module_methods_t*
get_module_methods()
{
static
hw_module_methods_t
_methods =
{
open: open_device
};
return &_methods;
}
static
camera_module
get_camera_module()
{
camera_module module = {
common:{
tag : HARDWARE_MODULE_TAG,
#if (PLATFORM_SDK_VERSION >= 21)
module_api_version : CAMERA_MODULE_API_VERSION_2_3,
#else
module_api_version : CAMERA_DEVICE_API_VERSION_1_0,
#endif
hal_api_version : HARDWARE_HAL_API_VERSION,
id : CAMERA_HARDWARE_MODULE_ID,
name : "MediaTek Camera Module",
author : "MediaTek",
methods : get_module_methods(),
dso : NULL,
reserved : {0},
},
get_number_of_cameras : get_number_of_cameras,
get_camera_info : get_camera_info,
set_callbacks : set_callbacks,
get_vendor_tag_ops : get_vendor_tag_ops,
#if (PLATFORM_SDK_VERSION >= 21)
open_legacy : open_legacy,
#endif
reserved : {0},
};
return module;
};
通過module->methods獲取到的函式為open_device,
static
int
open_device(hw_module_t const* module, const char* name, hw_device_t** device)
{
return NSCam::getCamDeviceManager()->open(device, module, name);
}
CamDeviceManagerImp 繼承了 CamDeviceManagerBase。這裡直接呼叫了CamDeviceManagerBase的open()status_t
CamDeviceManagerBase::
openDeviceLocked(
hw_device_t** device,
hw_module_t const* module,
int32_t const i4OpenId,
uint32_t device_version
)
{
// [2] get platform
IPlatform*const pPlatform = getPlatform();
pDevice = pPlatform->createCam1Device(s8ClientAppMode.string(), i4OpenId);
*device = const_cast<hw_device_t*>(pDevice->get_hw_device());
}
status_t
CamDeviceManagerBase::
open(
hw_device_t** device,
hw_module_t const* module,
char const* name,
uint32_t device_version
)
{
return openDeviceLocked(device, module, i4OpenId, device_version);
}
第11行, getPlatform函式用來載入libcam_platform.so,並獲取PlatformEntry介面
第12行, 構造一個Cam1Device物件,並呼叫它的init函式
第13行, 獲取camera device的操作集
4.2 getPlatform函式分析
static PlatformEntry g_PlatformEntry;
IPlatform*
getHandleToPlatform()
{
return &g_PlatformEntry;
}
IPlatform*
CamDeviceManagerBase::
getPlatform()
{
char const szModulePath[] = "libcam_platform.so";
char const szEntrySymbol[] = "getHandleToPlatform";
void* pfnEntry = NULL;
IPlatform* pIPlatform = NULL;
mpLibPlatform = ::dlopen(szModulePath, RTLD_NOW);
pfnEntry = ::dlsym(mpLibPlatform, szEntrySymbol);
pIPlatform = reinterpret_cast<IPlatform*(*)()>(pfnEntry)();
gIPlatform = pIPlatform;
return gIPlatform;
}
第18行, 載入libcam_platform.so
第19 20行, 獲取getHandleToPlatform函式入口,並呼叫,最後返回PlatformEntry介面
4.3 pPlatform->createCam1Device函式分析
NSCam::Cam1Device*
createCam1Device(
String8 const s8ClientAppMode,
int32_t const i4OpenId
)
{
NSCam::Cam1Device* pdev = NULL;
String8 const s8LibPath = String8::format("libcam.device1.so");
void *handle = ::dlopen(s8LibPath.string(), RTLD_GLOBAL);
String8 const s8CamDeviceInstFactory = String8::format("createCam1Device_Default");
void* pCreateInstance = ::dlsym(handle, s8CamDeviceInstFactory.string());
pdev = reinterpret_cast<NSCam::Cam1Device* (*)(String8 const&, int32_t const)>
(pCreateInstance)(s8ClientAppMode, i4OpenId);
pdev->initialize();
}
ICamDevice*
PlatformEntry::
createCam1Device(
char const* szClientAppMode,
int32_t const i4OpenId
)
{
return ::createCam1Device(String8(szClientAppMode), i4OpenId);
}
pPlatform->createCam1Device函式呼叫的是Cam1DeviceFactory.cpp裡的createCam1Device函式
第10行, 載入libcam.device1.so
第12-15行, 獲取createCam1Device_Default函式入口並呼叫
第17行, Cam1Device初始化
先來看createCam1Device_Default函式,以及類的繼承關係
class Cam1DeviceBase : public Cam1Device
{
}
class DefaultCam1Device : public Cam1DeviceBase
{
}
NSCam::Cam1Device*
createCam1Device_Default(
String8 const& rDevName,
int32_t const i4OpenId
)
{
return new DefaultCam1Device(rDevName, i4OpenId);
}
接著看DefaultCam1Device的建構函式
Cam1Device::
Cam1Device()
{
::memset(&mDevice, 0, sizeof(mDevice));
mDevice.priv = this;
mDevice.common = gHwDevice;
mDevice.ops = (camera_device_ops*)&mDeviceOps;
mDeviceOps = gCameraDevOps;
}
Cam1DeviceBase::
Cam1DeviceBase(
String8 const& rDevName,
int32_t const i4OpenId
)
: Cam1Device()
, mDevName(rDevName)
, mi4OpenId(i4OpenId)
{
MY_LOGD("");
}
DefaultCam1Device::
DefaultCam1Device(
String8 const& rDevName,
int32_t const i4OpenId
)
: Cam1DeviceBase(rDevName, i4OpenId)
{
}
刪除了一些暫不關注的程式碼,DefaultCam1Device的建構函式會不斷呼叫父類的建構函式,需要關注的是它的父類Cam1Device的建構函式。其中的gCameraDevOps結構體很重要,是Camera Device的操作集,預覽、拍照、錄影都是通過它來操作,來看下它的定義
static mtk_camera_device_ops const
gCameraDevOps =
{
#define OPS(name) name: camera_##name
{
OPS(set_preview_window),
OPS(set_callbacks),
OPS(enable_msg_type),
OPS(disable_msg_type),
OPS(msg_type_enabled),
OPS(start_preview),
OPS(stop_preview),
OPS(preview_enabled),
OPS(store_meta_data_in_buffers),
OPS(start_recording),
OPS(stop_recording),
OPS(recording_enabled),
OPS(release_recording_frame),
OPS(auto_focus),
OPS(cancel_auto_focus),
OPS(take_picture),
OPS(cancel_picture),
OPS(set_parameters),
OPS(get_parameters),
OPS(put_parameters),
OPS(send_command),
OPS(release),
OPS(dump)
},
OPS(mtk_set_callbacks),
#undef OPS
};
回到createCam1Device函式,最後呼叫了pdev->initialize函式,這個函式過程比較複雜,在它的父類Cam1DeviceBase中實現
bool
DefaultCam1Device::
onInit()
{
// (1) power on sensor
if( pthread_create(&mThreadHandle, NULL, doThreadInit, this) != 0 )
{
goto lbExit;
}
// (2) Open 3A
mpHal3a = NS3A::IHal3A::createInstance(
NS3A::IHal3A::E_Camera_1,
getOpenId(),
LOG_TAG);
// (3) Init Base.
if ( ! Cam1DeviceBase::onInit() )
{
goto lbExit;
}
}
status_t
Cam1DeviceBase::
initialize()
{
onInit();
return OK;
}
initialize函式只是簡單的回調了onInit函式,如註釋所示,主要做了3件事情。其中(2)和(3)主要是初始化3A和CamClient,這兩個這裡暫時不會關注,所以暫時不進行分析。重點關注(1),也就是doThreadInit函式
bool
DefaultCam1Device::
powerOnSensor()
{
IHalSensorList* pHalSensorList = IHalSensorList::get();
mpHalSensor = pHalSensorList->createSensor(USER_NAME, getOpenId());
sensorIdx = getOpenId();
if( !mpHalSensor->powerOn(USER_NAME, 1, &sensorIdx) )
{
MY_LOGE("sensor power on failed: %d", sensorIdx);
goto lbExit;
}
......
}
void*
DefaultCam1Device::
doThreadInit(void* arg)
{
DefaultCam1Device* pSelf = reinterpret_cast<DefaultCam1Device*>(arg);
pSelf->mRet = pSelf->powerOnSensor();
pthread_exit(NULL);
return NULL;
}
doThreadInit函式只是回撥自身的了powerOnSensor函式,而powerOnSensor函式先呼叫pHalSensorList->createSensor函式建立一個HalSensor例項,然後再呼叫它的PowerOn函式來開始相關的硬體操作,來看powerOn的實現
MBOOL
HalSensor::
powerOn(
char const* szCallerName,
MUINT const uCountOfIndex,
MUINT const*pArrayOfIndex
)
{
......
ret = mpSeninfDrv->init();
ret = mpSensorDrv->init(sensorDev);
ret = setTgPhase(sensorDev, pcEn);
ret = setSensorIODrivingCurrent(sensorDev);
ret = mpSensorDrv->open(sensorDev);
......
}
powerOn函式比較長,這裡暫時只關注SensorDrv的init和open函式MINT32
ImgSensorDrv::init(MINT32 sensorIdx)
{
m_fdSensor = ::open("dev/kd_camera_hw", O_RDWR);
//set driver
ret = ioctl(m_fdSensor, KDIMGSENSORIOC_X_SET_DRIVER,sensorDrvInit);
//init resolution
pSensorResInfo[0] = &m_SenosrResInfo[0];
pSensorResInfo[1] = &m_SenosrResInfo[1];
ret = getResolution(pSensorResInfo);
if(SENSOR_MAIN & sensorIdx ) {
sensorDevId = SENSOR_MAIN;
FeatureParaLen = sizeof(MUINTPTR);
ret = featureControl((CAMERA_DUAL_CAMERA_SENSOR_ENUM)sensorDevId, SENSOR_FEATURE_GET_PIXEL_CLOCK_FREQ, (MUINT8*)&FeaturePara32,(MUINT32*)&FeatureParaLen);
FeatureParaLen = sizeof(pFeaturePara16);
ret = featureControl((CAMERA_DUAL_CAMERA_SENSOR_ENUM)sensorDevId, SENSOR_FEATURE_GET_PERIOD, (MUINT8*)pFeaturePara16,(MUINT32*)&FeatureParaLen);
}
......
}
MINT32
ImgSensorDrv::open(MINT32 sensorIdx)
{
MINT32 err = SENSOR_NO_ERROR;
......
err = ioctl(m_fdSensor, KDIMGSENSORIOC_X_SET_CURRENT_SENSOR, &sensorIdx);
err = ioctl(m_fdSensor, KDIMGSENSORIOC_T_OPEN);
return err;
}
這兩個函式邏輯比較簡單,就是通過ioctl進入到kernel層來對sensor硬體進行初始化和獲取硬體相關的資訊。kernel層的程式碼暫不分析
4.4 get_hw_device函式分析
回到4.1的openDeviceLocked函式,最後呼叫了pDevice->get_hw_device函式,並將它的返回值賦給*device
class Cam1Device : public ICamDevice
{
virtual hw_device_t const* get_hw_device() const { return &mDevice.common; }
}
這個函式很簡單,就是獲取4.3裡面提到的mDevice,這個mDevice最終將被儲存在frameworks層的CameraHardwareInterface.h的mDevice變數當中,以便日後訪問
5. 總結
Camera開啟流程的重點工作在4.3和4.4章節,也就是對Camera硬體進行初始化和將gCameraDevOps操作集返回給frameworks層。
相關推薦
Android 5.0 Camera系統原始碼分析(2):Camera開啟流程
1. 前言 本文將分析android系統原始碼,從frameworks層到hal層,暫不涉及app層和kernel層。由於某些函式比較複雜,在貼出程式碼時會適當對其進行簡化。本文屬於自己對原始碼的總結,僅僅是貫穿程式碼流程,不會深入分析各個細節。歡迎聯絡討論,QQ:1026
Android 5.0 Camera系統原始碼分析(4):Camera預覽流程資料流
1. 前言 上一篇講了怎麼讓Camera進入預覽模式,提到了DisplayClient負責顯示影象資料,而CamAdapter負責提供影象資料,這裡主要記錄了CamAdapter怎麼獲取影象,然後DisplayClient怎麼將影象顯示在螢幕上。 2.
Android 5.0 Camera系統原始碼分析(3):Camera預覽流程控制流
1. 前言 本文分析的是Android系統原始碼,從frameworks層到hal層,記錄了Camera進入預覽模式的重點程式碼,主要為控制流程的程式碼,有關影象buffer的傳遞暫不涉及,硬體平臺基於mt6735。由於某些函式比較複雜,在貼出程式碼時會適當對
Android 5.0 Usb除錯攔截分析及修改
當我們除錯安卓機器時,第一次插上usb線,會彈出一個授權的對話方塊,(前提是打開了usb除錯功能)點選確認,才會允許除錯. 如果我們想機器預設就可以除錯該怎麼做呢? 如果我們想動態攔截,需要使用者輸入帳號密碼,才確認是否可以除錯,該怎麼做呢?或者只是單純的想改變這個不好看
Android應用程式啟動過程原始碼分析(2)
Step 9. ActivityStack.startActivityUncheckedLocked 這個函式定義在frameworks/base/services/java/com/android/server/am/ActivityStack.java檔案中: view plain pu
coreutils4.5.1 expr.c 原始碼分析2
今天又開始讀程式碼。前段時間看演算法分析相關的書,蒐集了不少演算法相關書籍,感覺自己功力太淺,還是讀讀原始碼吧。好在,讀小說,養成了快速讀書的好習慣,再加不求甚解,把快速+不求甚解利用到讀程式碼上,感覺也很有意思。 今天重點翻了翻expr.c,這個原始碼,很有特色,首先啟用debug功能。 文件中有
android 5.0 64bit系統載入庫檔案失敗問題淺析
最近公司的一個專案使用android 5.0 64 bit平臺,相對以前版本,除了android 5.0 有很大變動之外,64 bit系統和32 bit系統也存在很多差異性。 目前碰到的問題就是以前在32位上的so庫檔案,到64 位系統上不能載入的問題。首先來看一下相關lo
Android 7.0 Gallery相簿原始碼分析8
在Android 7.0 Gallery相簿原始碼分析3 - 資料載入及顯示流程一文最後講了AlbumSetSlidingWindow的onContentChanged方法,專輯縮圖和縮圖下面的label的載入就是在此方法中完成的 public
React Native之Android 5.0以下系統WebView訪問https頁面變成空白頁
在我們的React Native專案中,需要開發一個tab頁面專門配置三方h5連結,供使用者瀏覽。自動化測試:Android 5.0以下系統此tab頁面為空白頁面。看效果: 而我們去檢視這個三方的
Android 7.0 Gallery相簿原始碼分析4
上篇文章講了初始化View時會例項化一個SlotView並監聽其事件,至於它是怎麼實現的,用的是Android自帶的GestureDetector。 GestureDetector是Android自帶的用來監聽各種使用者手勢的的一個類,比如監聽單擊、雙擊和
android 5.0以下系統Intent傳遞序列化物件的bug
專案中使用外掛框架,當外掛在Intent中傳遞Serializable物件時,在android 5.0以下系統上會出現 E/InstrumentationHacker(25176): Parcelable encounteredClassNotFoundExce
Android 5.0核心和原始碼學習(3)——SystemServer啟動了什麼服務?
/**入口 * The main entry point from zygote. */ public static void main(String[] args) { new SystemServer().run(); } /**
LAV Filter 原始碼分析 2: LAV Splitter
LAV Filter 中最著名的就是 LAV Splitter,支援Matroska /WebM,MPEG-TS/PS,MP4/MOV,FLV,OGM / OGG,AVI等其他格式,廣泛存在於各種視訊播放器(暴風影音這類的)之中。本文分析一下它的原始碼。在分析之前,先看看它是
Linux-0.11核心原始碼分析系列:記憶體管理get_free_page()函式分析
Linux-0.11記憶體管理模組是原始碼中比較難以理解的部分,現在把筆者個人的理解發表 先發Linux-0.11核心記憶體管理get_free_page()函式分析有時間再寫其他函式或者檔案的:) /* *Author : DavidLin *Date :
SpringMVC原始碼分析2:SpringMVC設計理念與DispatcherServlet
轉自:https://my.oschina.net/lichhao/blog SpringMVC簡介 SpringMVC作為Struts2之後異軍突起的一個表現層框架,正越來越流行,相信javaee的開發者們就算沒使用過SpringMVC,也應該對其略有耳聞。我試圖通過對SpringMVC的設計思想和原始碼實
WebRTC原始碼分析三:視訊處理流程
文字介紹視訊的處理流程。圖1中顯示了兩路視訊會話視訊訊號流過程。 圖1 視訊流程示意圖 以一路視訊會話為例,主要分為以下幾個執行緒: 1)視訊源產生執行緒:Camera生產視訊畫面,封裝成視訊幀,以一定幀率投遞到下一個模組。; 2)採集執行緒:由Capturer負責採集視訊幀,並對視訊幀進行一定處理,如
Android Camera 系統架構原始碼分析(2)---->Camera的startPreview和setPreviewCallback
Camera startPreview流程 上接第一篇,這個過程的主要任務是,如何讀取資料的,讀取的資料是什麼格式,最好能知道是如何去預覽的 上層APP呼叫的是Camera.java的startPreview();,下面列出startPreview的呼叫流程 //Camera
Android 8.0系統原始碼分析--Binder程序間通訊(一)
開始我們的沉澱之路,老羅的書中第二章講的是Android HAL層的知識,而且直接自己實現了一個虛擬的freg驅動程式,後面的幾節是分別從native、java層如何訪問這個虛擬的驅動程式介面,我這裡沒有這樣的環境,所以就不分析這節了,第三章的智慧指標我對比8.0系統原
Android 8.0系統原始碼分析--openCamera(HAL)啟動過程原始碼分析
前面我們詳細分析了從應用層呼叫CameraManager的openCamera的方法來開啟相機的邏輯,上次的分析我們來到了CameraServer程序當中,但是還沒有真正看到open操作裝置節點來實現真正開啟的邏輯,遺留的問題也就是從frameworks\av\se
Android 8.0系統原始碼分析--Activity的視窗Window物件新增過程原始碼分析
這節我們來看一下Activity的視窗Window物件的建立過程,Activity作為Android提供的四大元件之首,我們之所以能非常簡單的使用它,就是因為它的建立過程中,framework為我們作了大量的初始化工作,包括它的視窗Window、視訊記憶體Surf