Android 调试

打开调试信息

需要打开logcat的日志,在所有头文件前面添加(后面的头文件会包含< utils/Log.h > ,其中会根据以下宏的取值打开或者关闭打印):
#define LOG_TAG “AndroidRuntime”
#undef NDEBUG //打开LOGV/LOGI/LOGD
#define LOG_NDEBUG 0 //打开LOGV,为1时表示禁止
#define LOG_NIDEBUG 0 //打开LOGI,为1时表示禁止
#define LOG_NDDEBUG 0 //打开LOGD,为1时表示禁止

对于安卓源码中需要打印到/proc/kmsg(dmesg)中的日志,比如uenvent.c中的日志,需要修改
system/core/include/cutils/klog.h文件中的打印等级,且打印等级必须高于内核中/kernel/printk.c的设置等级:
#define KLOG_DEFAULT_LEVEL 3

驱动设备测试

可以通过在/sys下添加读写测试节点测试驱动好坏:

struct pn544_dev *g_pn544_dev;
static ssize_t pn544_test_write(struct kobject *kobj,struct kobj_attribute *attr,
								const char *buf, size_t n)
{
	unsigned char count,i;
	unsigned char getdata[10];
	ssize_t ret;
	
	const char *buftmp = buf;
	sscanf(buftmp, "%x %x %x %x %x %x %x %x %x %x %x", &count, 
		&getdata[0], &getdata[1], &getdata[2], &getdata[3],&getdata[4],
		&getdata[5], &getdata[6], &getdata[7], &getdata[8],&getdata[9]);
	ret = i2c_master_send(g_pn544_dev->client, getdata, count);
	if (ret != count) 
	{
		pr_err("%s : i2c_master_send returned %d\n", __func__, ret);
		ret = -EIO;
		return ret;
	}
	printk("write %d bytes success:", count);
	for(i = 0 ; i < count ; i++)
		printk("%x ", getdata[i]);
	printk("\n");
	return n;
}
static ssize_t pn544_test_read(struct kobject *kobj, struct kobj_attribute *attr,char *buf)
{
	unsigned char i;
	unsigned char getdata[10];
	ssize_t ret;

	ret = i2c_master_recv(g_pn544_dev->client, getdata, 10);
	if (ret < 0) 
	{
		pr_err("%s: i2c_master_recv returned %d\n", __func__, ret);
		return ret;
	}
	if (ret > 10) 
	{
		pr_err("%s: received too many bytes from i2c (%d)\n", __func__, ret);
		ret = -EIO;
		return ret;
	}
	printk("read %d bytes success:", ret);
	for(i = 0 ; i < ret ; i++)
		printk("%x ", getdata[i]);
	printk("\n");
	sprintf(buf, "Read %d bytes success :%x %x %x %x %x %x x %x %x %x %x\n", ret , 
			getdata[0], getdata[1], getdata[2], getdata[3], getdata[4], 
			getdata[5], getdata[6], getdata[7], getdata[8], getdata[9]);
	return ret;
}
static struct kobject *pn544_kobj;
struct pn544_attribute {
		struct attribute	attr;
		ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr, char *buf);
		ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t n);
};
static struct pn544_attribute pn544_attrs[] = {
	/*     node_name	permision		show_func	store_func */
	__ATTR(pn544_test,	S_IRUSR | S_IWUSR,	pn544_test_read,	pn544_test_write),
};

/* probe函数中添加: */
g_pn544_dev = pn544_dev;
pn544_kobj = kobject_create_and_add("pn544_test", NULL);
if (!pn544_kobj)
	return -ENOMEM;
for (i = 0; i < ARRAY_SIZE(pn544_attrs); i++) {
	ret = sysfs_create_file(pn544_kobj, &pn544_attrs[i].attr);
	if (ret != 0) {
		printk("create index %d error\n", i);
		return ret;
	}
}

mm -jn单独编译模块(重新编译用mm -B -jn,自动编译依赖使用mma -B -jn)

单独编译模块,可以打开Android.mk查看目标模块的名字,以找到模块对应的.jar或者.so
当存在多个模块名的时候,请注意模块所包含的源文件和编译最后的Install命令,看产生了什么.jar或者.so
如果Android.mk中没有LOCAL_MODULE,或者mm之后没有产生Install文件,说明需要在上一级目录编译
生成的.jar或者.so可以通过以下命令进行推送调试
adb root
adb remount rw(失败时可以先进入shell,执行mount -o remount rw /)
注意remount后的分区必须为ext格式才能使用chmod更改权限,其他如fat32分区虽然不报错,也不会有效果
adb push a.jar /system/lib/…
adb reboot
make snod 可以重新打包system.img

编译清理

严格性依次为
make clean-module_name 清除单个模块
make installclean 删除out目录下的install文件,由于system.img文件大部分并非通过依赖关系生成,而是通过打包生成,因此改动了编译mk规则之后,经常需要清除out目录下的目标文件,重新make
make clean 清理,不解释
make clobber 清理包括编译配置信息,更加彻底
清理之后需要 lunch来进行编译项选择

lunch命令选项

user
仅安装标签为 user 的模块
设定属性 ro.secure=1,打开安全功能
设定属性 ro.adb.secure=1,需要adb调试身份校验
设定属性 ro.debuggable=0,关闭应用调试功能,不允许通过adb root获取root权限
默认关闭 adb 功能
打开 Proguard 混淆器
打开 DEXPREOPT 预先编译优化

userdebug
安装标签为 user、debug 的模块
设定属性 ro.secure=1,打开安全功能
设定属性 ro.adb.secure=1,需要adb调试身份校验
设定属性 ro.debuggable=1,启用应用调试功能,即允许adb通过adb root获取root权限
默认打开 adb 功能
打开 Proguard 混淆器
打开 DEXPREOPT 预先编译优化

eng
安装标签为 user、debug、eng 的模块
设定属性 ro.secure=0,关闭安全功能,即默认adb使用root权限
设定属性 ro.adb.secure=1,需要adb调试身份校验
设定属性 ro.debuggable=1,启用应用调试功能
设定属性 ro.kernel.android.checkjni=1,启用 JNI 调用检查
默认打开 adb 功能
关闭 Proguard 混淆器
关闭 DEXPREOPT 预先编译优化

adb中的中文显示问题

1.打开cmd,输入chcp查看当前字符编码,一般为GBK936;
2.输入“chcp 65001”更改char codepage为utf-8;
3.在cmd的默认值属性中,将字体设置为中文字体,如"新宋体"。

常用路径

frameworks/native/services/inputflinger

frameworks/base/services/core/jni

frameworks/base/core/java/android/app
frameworks/base/core/java/android/hardware/display

system/displayd

source build/envsetup.sh后的命令

mma 可以根据模块依赖关系,编译所有与当前目录下的模块关联的程序。
cgrep 只查找C、C++文件
ggrep 只查找Gradle文件
jgrep 只查找Java文件
resgrep 只查找res/*.xml文件
mangrep 只查找AndroidManifest.xml文件
sepgrep 只查找sepolicy文件
sgrep 查找所有源文件
croot 返回源码根目录
godir 进入包含源码文件名的目录

命令行启动APP

am start -n {包名(package)}/{包名}.{活动名称(activity)}
程序的入口类可以从每个应用的AndroidManifest.xml的文件中得到,以计算器(calculator)为例,它的

<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.calculator2">

    <application
        android:icon="@mipmap/ic_launcher_calculator"
        android:label="@string/app_name"
        android:theme="@style/CalculatorTheme">

        <activity
            android:name=".Calculator"
            android:label="@string/app_name"
            android:windowSoftInputMode="stateAlwaysHidden">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
                <category android:name="android.intent.category.APP_CALCULATOR" />
            </intent-filter>
        </activity>

    </application>

</manifest>

由此计算器(calculator)的启动方法为:# am start -n com.android.calculator2/com.android.calculator2.Calculator

提取内置安装包

1.adb shell pm list packages找到要提取apk的包名
2.adb shell pm path 定位apk所在系统路径
3.adb pull [] 从手机把apk pull下来

Android.mk

LOCAL_MODULE_TAGS :=user eng tests optional

user: 指该模块只在user版本下才编译,高版本AOSP不可直接使用,优选optional

eng: 指该模块只在eng版本下才编译

tests: 指该模块只在tests版本下才编译

optional:指该模块在所有版本下都编译,根目录下make,该模块仅编译,但不会install,需要在PRODUCT_PACKAGES 中添加报名才会自动安装到system.img

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值