Ⅰ 如何用adroid studio 如何阅读android源码
在android源码中有一个目录idegen,是生成ide的project文件,主要是生成intellij的project文件,用source insight阅读Android源码,效果非常好。
过程:
效果图;
导入到android studio,打开Android studio,点击File > Open,选择刚刚生成的android.ipr就好了;
备注:
可以结合android studio,界面,智能提示都比source insight要好。
Ⅱ 如何高效阅读android反编译后的源码
一、工具准备:apktool , dex2jar , jd-gui
二、使用dex2jar + jd-gui 得到apk的java源码
1.用解压工具从 apk包中取出 classes.dex 文件
用命令(dex2jar.bat classes.dex)得到一个 jar文件
2.用jd-gui反编译工具将得到.jar文件反编译成.java文件
三、使用apktool得到apk的xml文件
用命令(apktool d xxx.apk xxx_xml)反编译xxx.apk包2.从 xxx_xml 文件夹得到xml文件四、第二步 得到的程序源代码 和 第三步 得到的xml文件组合下,即可得到完整的apk源码。
五、应用: 汉化/去广告,加 values-zh-rCN, values-zh-rTW, values-de, values-fr
1.在步骤三的文件夹xxx_xml/res/ 下, 建文件夹: values-zh-rCN,values-zh-rTW
2.1复制valuesstrings.xml 到 values-zh-rCN 并翻译.
2.2 去广告见;
3.重建APK,用命令(apktool b xxx) ,输出到ABC/dist/out.apk
或命令( apktool b xxx out.apk)
详细代码
Ⅲ 如何阅读android framework源码
首先看MediaRecorder.java内的setVideoEncoder方法:
/**
* Sets the video encoder to be used for recording. If this method is not
* called, the output file will not contain an video track. Call this after
* setOutputFormat() and before prepare().
*
* @param video_encoder the video encoder to use.
* @throws IllegalStateException if it is called before
* setOutputFormat() or after prepare()
* @see android.media.MediaRecorder.VideoEncoder
*/
public native void setVideoEncoder(int video_encoder)
throws IllegalStateException;123456789101112
这是一个native方法,根据JNI的规则,我们应该去android_media_MediaRecorder.cpp里看这个方法的实现:
static void
android_media_MediaRecorder_setVideoEncoder(JNIEnv *env, jobject thiz, jint ve)
{
ALOGV("setVideoEncoder(%d)", ve);
if (ve < VIDEO_ENCODER_DEFAULT || ve >= VIDEO_ENCODER_LIST_END) {
jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid video encoder");
return;
}
sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
process_media_recorder_call(env, mr->setVideoEncoder(ve), "java/lang/RuntimeException", "setVideoEncoder failed.");
}1234567891011
关键是最后的两句,sp是Android 里的一个指针,就当没看见~ 所以最后两句的意思是调用Native层的MediaRecorder的setVideoEncoder方法。
继续去MediaRecorder.cpp里看setVideoEncoder方法:
status_t MediaRecorder::setVideoEncoder(int ve)
{
ALOGV("setVideoEncoder(%d)", ve);
if (mMediaRecorder == NULL) {
ALOGE("media recorder is not initialized yet");
return INVALID_OPERATION;
}
if (!mIsVideoSourceSet) {
ALOGE("try to set the video encoder without setting the video source first");
return INVALID_OPERATION;
}
if (mIsVideoEncoderSet) {
ALOGE("video encoder has already been set");
return INVALID_OPERATION;
}
if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
ALOGE("setVideoEncoder called in an invalid state(%d)", mCurrentState);
return INVALID_OPERATION;
}
status_t ret = mMediaRecorder->setVideoEncoder(ve);
if (OK != ret) {
ALOGV("setVideoEncoder failed: %d", ret);
mCurrentState = MEDIA_RECORDER_ERROR;
return ret;
}
mIsVideoEncoderSet = true;
return ret;
}
这里的mMediaReocorder定义在MediaRecorder.h里:
sp<IMediaRecorder> mMediaRecorder;1
可见其是一个IMediaRecorder类型的变量,这是一个接口类型,看一下其接口定义,在IMediaRecorder.h中:
class IMediaRecorder: public IInterface
{
public:
DECLARE_META_INTERFACE(MediaRecorder);
virtual status_t setCamera(const sp<hardware::ICamera>& camera,
const sp<ICameraRecordingProxy>& proxy) = 0;
virtual status_t setPreviewSurface(const sp<IGraphicBufferProcer>& surface) = 0;
virtual status_t setVideoSource(int vs) = 0;
virtual status_t setAudioSource(int as) = 0;
virtual status_t setOutputFormat(int of) = 0;
virtual status_t setVideoEncoder(int ve) = 0;
virtual status_t setAudioEncoder(int ae) = 0;
virtual status_t setOutputFile(int fd, int64_t offset, int64_t length) = 0;
virtual status_t setVideoSize(int width, int height) = 0;
virtual status_t setVideoFrameRate(int frames_per_second) = 0;
virtual status_t setParameters(const String8& params) = 0;
virtual status_t setListener(const sp<IMediaRecorderClient>& listener) = 0;
virtual status_t setClientName(const String16& clientName) = 0;
virtual status_t prepare() = 0;
virtual status_t getMaxAmplitude(int* max) = 0;
virtual status_t start() = 0;
virtual status_t stop() = 0;
virtual status_t reset() = 0;
virtual status_t pause() = 0;
virtual status_t resume() = 0;
virtual status_t init() = 0;
virtual status_t close() = 0;
virtual status_t release() = 0;
virtual status_t setInputSurface(const sp<IGraphicBufferConsumer>& surface) = 0;
virtual sp<IGraphicBufferProcer> querySurfaceMediaSource() = 0;
};
// ----------------------------------------------------------------------------
class BnMediaRecorder: public BnInterface<IMediaRecorder>
{
public:
virtual status_t onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
};3031323334353637383940414243
呐~关键的步骤来了,在以前我基本就追到这,就算完蛋了,不知道怎么继续往下追了,后来看Binder相关的内容,知道了BnInterface的作用,这是Binder中关键的一环,我们这就不展开讲了,只要记得,接下来我们要追的是BnMediaRecorder这个类。
全局搜索一下“: public BnMediaRecorder”,也就是去找它的实现类,发现在MediaRecorderClient.h当中有如下的定义:
class MediaRecorderClient : public BnMediaRecorder
{
class ServiceDeathNotifier: public IBinder::DeathRecipient
{
public:
ServiceDeathNotifier(
const sp<IBinder>& service,
const sp<IMediaRecorderClient>& listener,
int which);
virtual ~ServiceDeathNotifier();
virtual void binderDied(const wp<IBinder>& who);
private:
int mWhich;
sp<IBinder> mService;
wp<IMediaRecorderClient> mListener;
};
public:
virtual status_t setCamera(const sp<hardware::ICamera>& camera,
const sp<ICameraRecordingProxy>& proxy);
virtual status_t setPreviewSurface(const sp<IGraphicBufferProcer>& surface);
virtual status_t setVideoSource(int vs);
virtual status_t setAudioSource(int as);
virtual status_t setOutputFormat(int of);
virtual status_t setVideoEncoder(int ve);
virtual status_t setAudioEncoder(int ae);
virtual status_t setOutputFile(int fd, int64_t offset,
int64_t length);
virtual status_t setVideoSize(int width, int height);
virtual status_t setVideoFrameRate(int frames_per_second);
virtual status_t setParameters(const String8& params);
virtual status_t setListener(
const sp<IMediaRecorderClient>& listener);
virtual status_t setClientName(const String16& clientName);
virtual status_t prepare();
virtual status_t getMaxAmplitude(int* max);
virtual status_t start();
virtual status_t stop();
virtual status_t reset();
virtual status_t pause();
virtual status_t resume();
virtual status_t init();
virtual status_t close();
virtual status_t release();
virtual status_t mp(int fd, const Vector<String16>& args);
virtual status_t setInputSurface(const sp<IGraphicBufferConsumer>& surface);
virtual sp<IGraphicBufferProcer> querySurfaceMediaSource();
private:
friend class MediaPlayerService; // for accessing private constructor
MediaRecorderClient(
const sp<MediaPlayerService>& service,
pid_t pid,
const String16& opPackageName);
virtual ~MediaRecorderClient();
sp<IBinder::DeathRecipient> mCameraDeathListener;
sp<IBinder::DeathRecipient> mCodecDeathListener;
pid_t mPid;
Mutex mLock;
MediaRecorderBase *mRecorder;
sp<MediaPlayerService> mMediaPlayerService;
};303132333435363738394
那么我们去MediaRecorderClient.cpp里看看:
status_t MediaRecorderClient::setVideoEncoder(int ve)
{
ALOGV("setVideoEncoder(%d)", ve);
Mutex::Autolock lock(mLock);
if (mRecorder == NULL) {
ALOGE("recorder is not initialized");
return NO_INIT;
}
return mRecorder->setVideoEncoder((video_encoder)ve);
}12345678910
这里的mRecorder 定义在MediaRecorderClient.h当中:
MediaRecorderBase *mRecorder;1
来,我们继续搜索“: public MediaRecorderBase”,在StagefrightRecorder.h中找到了,那么我们去StagefrightRecorder.cpp当中看看~
status_t StagefrightRecorder::setVideoEncoder(video_encoder ve) {
ALOGV("setVideoEncoder: %d", ve);
if (ve < VIDEO_ENCODER_DEFAULT ||
ve >= VIDEO_ENCODER_LIST_END) {
ALOGE("Invalid video encoder: %d", ve);
return BAD_VALUE;
}
mVideoEncoder = ve;
return OK;
}123456789101112
呐,这就算完了~最后我们会发现MediaRecorder中的接口实现基本到最后都会落在这个StagefrightRecorder.cpp当中。
Ⅳ 大牛们是怎么阅读 Android 系统源码的
如果只是想看看一些常用类的实现, 在Android包管理器里把源码下载下来, 随便一个IDE配好Source Code的path看就行.
但如果想深入的了解Android系统, 那么可以看下我的一些简单的总结.
知识
Java
Java是AOSP的主要语言之一. 没得说, 必需熟练掌握.
熟练的Android App开发
Linux
Android基于Linux的, 并且AOSP的推荐编译环境是Ubuntu 12.04. 所以熟练的使用并了解Linux这个系统是必不可少的. 如果你想了解偏底层的代码, 那么必需了解基本的Linux环境下的程序开发. 如果再深入到驱动层, 那么Kernel相关的知识也要具备.
Make
AOSP使用Make系统进行编译. 了解基本的Makefile编写会让你更清晰了解AOSP这个庞大的项目是如何构建起来的.
Git
AOSP使用git+repo进行源码管理. 这应该是程序员必备技能吧.
C++
Android系统的一些性能敏感模块及第三方库是用C++实现的, 比如: Input系统, Chromium项目(WebView的底层实现).
硬件
流畅的国际网络
AOSP代码下载需要你拥有一个流畅的国际网络. 如果在下载代码这一步就失去耐心的话, 那你肯定没有耐心去看那乱糟糟的AOSP代码. 另外, 好程序员应该都会需要一个流畅的Google.
一台运行Ubuntu 12.04的PC.
如果只是阅读源码而不做太多修改的话, 其实不需要太高的配置.
一台Nexus设备
AOSP项目默认只支持Nexus系列设备. 没有也没关系, 你依然可以读代码. 但如果你想在大牛之路走的更远, 还是改改代码, 然后刷机调试看看吧.
高品质USB线
要刷机时线坏了, 没有更窝心的事儿了.
软件
Ubuntu 12.04
官方推荐, 没得选.
Oracle Java 1.6
注意不要用OpenJDK. 这是个坑, 官方文档虽然有写, 但还是单独提一下.
安装:
sudo apt-get install python-software-properties
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java6-installer
sudo apt-get install oracle-java6-set-default
Eclipse
估计会有不少人吐槽, 为什么要用这个老古董. 其实原因很简单, 合适. 刚开始搞AOSP时, 为了找到效率最优的工具, 我尝试过Eclipse, IntelliJ IDEA, Vim+Ctags, Sublime Text+Ctags. 最终结果还是Eclipse. 主要优点有:
有语法分析 (快速准确的类, 方法跳转).
支持C++ (IntelliJ的C++支持做的太慢了).
嵌入了DDMS, View Hierarchy等调试工具.
为了提高效率, 花5分钟背下常用快捷键非常非常值得.
调整好你的classpath, 不要导入无用的代码. 因为AOSP项目代码实在是太多了. 当你还不需要看C++代码时, 不要为项目添加C++支持, 建索引过程会让你崩溃.
Intellij IDEA
开发App必备. 当你要调试系统的某个功能是, 常常需要迅速写出一个调试用App, 这个时候老旧的Eclipse就不好用了. Itellij IDEA的xml自动补全非常给力.
巨人的肩膀
这个一定要先读. 项目介绍, 代码下载, 环境搭建, 刷机方法, Eclipse配置都在这里. 这是一切的基础.
这个其实是给App开发者看的. 但是里面也有不少关于系统机制的介绍, 值得细读.
此老罗非彼老罗. 罗升阳老师的博客非常有营养, 基本可以作为指引你开始阅读AOSP源码的教程. 你可以按照博客的时间顺序一篇篇挑需要的看.但这个系列的博客有些问题:
早期的博客是基于旧版本的Android;
大量的代码流程追踪. 读文章时你一定要清楚你在看的东西在整个系统处于什么样的位置.
邓凡平老师也是为Android大牛, 博客同样很有营养. 但是不像罗升阳老师的那么系统. 更多的是一些技术点的深入探讨.
Android官方Issue列表. 我在开发过程中发现过一些奇怪的bug, 最后发现这里基本都有记录. 当然你可以提一些新的, 有没有人改就是另外一回事了.
一定要能流畅的使用这个工具. 大量的相关知识是没有人系统的总结的, 你需要自己搞定.
其它
代码组织
AOSP的编译单元不是和git项目一一对应的, 而是和Android.mk文件一一对应的. 善用mmm命令进行模块编译将节省你大量的时间.
Binder
这是Android最基础的进程间通讯. 在Application和System services之间大量使用. 你不仅要知道AIDL如何使用, 也要知道如何手写Binder接口. 这对你理解Android的Application和System services如何交互有非常重要的作用. Binder如何实现的倒不必着急看.
HAL
除非你对硬件特别感兴趣或者想去方案公司上班, 否则别花太多时间在这一层.
CyanogenMod
这是一个基于AOSP的第三方Rom. 从这个项目的wiki里你能学到很多AOSP官方没有告诉你的东西. 比如如何支持Nexus以外的设备.
DIA
这是一个Linux下画UML的工具, 能够帮你梳理看过的代码.
XDA
Ⅳ 如何阅读Android系统源码
Android源码两个部分看得最多,一个是packages,就是各个系统应用的实现,另外就是framework,框架层的实现。 具体看什么就看你想了解什么。 工具eclipse也很好,build一下生成class path,各种转跳非常方便,不需要grep了。