发布网友 发布时间:2022-04-23 02:43
共3个回答
懂视网 时间:2022-04-30 14:33
什么是aapt?
执行命令: C:UsersXiaopeng>aapt
Android Asset Packaging Tool
1、列出apk包的内容
aapt l[ist] [-v] [-a] file.{zip,jar,apk}
注:filepath是apk存放的路径
aapt l -v filepath/..apk:以table的形式列出来(不过我用起来老是出,win7和xp都一样,大家可以试一下)
aapt l -a filepath/..apk:详细的列出apk的内容
由于内容太多,我们把内容都存放到txt文件里,打开查看
aapt l filepath/..apk:查看apk内容
由于内容太多,我们把内容都存放到txt文件里,打开查看
对比一下可以看出,aapt l -a filepath/..apk 显示的apk内容更详细。
2、查看apk的一些信息
aapt d[ump] [--values] WHAT file.{apk} [asset [asset ...]]
badging Print the label and icon for the app declared in APK.
permissions Print the permissions from the APK.
resources Print the resource table from the APK.
configurations Print the configurations in the APK.
xmltree Print the compiled xmls in the given assets.
xmlstrings Print the strings of the given compiled xml assets.
aapt d badging filepath/..apk :显示标签、图标和应用程序的相关描述。
(这个命令很有用啊,我写过一个自动化更新下载的程序,就用到这个命令来校验应用的包名、版本和权限)
aapt d permissions filepath/..apk :显示apk所具有的系统权限
aapt d badging filepath/..apk : 显示apk的资源列表 (很多内容,如果想看最好还是转到txt里面查看吧)
aapt d configurations filepath/..apk : 显示apk的配置信息
aapt d xmltree filepath/..apk xmlname : 以树型显示apk中某个xml文件
例:以树型显示QQapk中 AndroidManifest.xml文件
aapt d xmlstrings filepath/..apk xmlname : 显示apk中某个xml文件中所有的字符
例:显示QQapk中 AndroidManifest.xml中的字符
3、编译android资源
aapt p[ackage] [-d][-f][-m][-u][-v][-x][-z][-M AndroidManifest.xml]
[-0 extension [-0 extension ...]] [-g tolerance] [-j jarfile]
[--debug-mode] [--min-sdk-version VAL] [--target-sdk-version VAL]
[--app-version VAL] [--app-version-name TEXT] [--custom-package VAL]
[--rename-manifest-package PACKAGE]
[--rename-instrumentation-target-package PACKAGE]
[--utf16] [--auto-add-overlay]
[--max-res-version VAL]
[-I base-package [-I base-package ...]]
[-A asset-source-dir] [-G class-list-file] [-P public-definitions-file]
[-S resource-sources [-S resource-sources ...]]
[-F apk-file] [-J R-file-dir]
[--product product1,product2,...]
[-c CONFIGS] [--preferred-configurations CONFIGS]
[-o]
[raw-files-dir [raw-files-dir] ...]
解释:
-f 如果编译出来的文件已经存在,强制覆盖
-m 使生成的包的目录存放在-J参数指定的目录
-J 指定生成的R.java 的输出目录
-S res文件夹路径
-A assert文件夹路径
-I 某个版本平台的android.jar的路径
-F 具体指定APK文件的输出
实例:
一.将工程的资源编译到R.java文件
aapt package -m -J <R.java文件夹> -S <res路径> -I <android.jar路径> -M<AndroidManifest.xml路径>
实例:
1.cmd -- 定位到android源文件目录,如: cd E:wirelessqahi --- 根据上面给出的命令套进去
<R.java文件夹> :gencomperf
<res路径>: res
<android.jar路径> :
E:Softwareandroid-sdk-windows-1.6_r1platformsandroid-1.6android.jar 这个要看你apk对应支持的android版本
这里有很多,找到对应的
<AndroidManifest.xml路径>: AndroidManifest.xml
OK,执行命令:
aapt p -f -m -J gencomperf -S res -I E:Softwareandroid-sdk-windows-1.6_r1platformsandroid-1.6android.jar -M AndroidManifest.xml
二.将工程的资源编译到一个APK包里
aapt package -f -S <res路径> -I <android.jar路径> -A <assert路径> -M <AndroidManifest.xml路径> -F <输出的包目录+包名>
实例:
1.cmd -- 定位到android源文件目录,如: cd E:wirelessqahi --- 根据上面给出的命令套进去
<res路径>: res
<android.jar路径>:
E:Softwareandroid-sdk-windows-1.6_r1platformsandroid-1.6android.jar
<assert路径> :assets
<AndroidManifest.xml路径>: 当前目录下的 AndroidManifest.xml
<输出的包目录+包名>: 当前目录下 hi.apk
OK,执行命令:
aapt p -f -S res -I E:Softwareandroid-sdk-windows-1.6_r1platformsandroid-1.6android.jar -A assets -M AndroidManifest.xml -F hi.apk
4. 移除打包好的apk中的文件
aapt r[emove] [-v] file.{zip,jar,apk} file1 [file2 ...]
实例:将apk中的某个文件移除掉
命令:aapt r <你的apk文件路径> <想要移除的文件名>
先从hi.apk除除AndroidManifest.xml文件,再尝试去显示,结果无法找到,证明我们已经移除成功。
5.添加文件到打包好的apk中
aapt a[dd] [-v] file.{zip,jar,apk} file1 [file2 ...]
实例:将文件添加到打包好的apk文件中
命令:aapt a <你的apk文件路径> <想要添加的文件路径>
在这里我遇到一个问题,添加文件成功之后再去尝试显示文件,结果提示文件损坏,至于是什么问题我还不知道,如果大家谁知道可以告诉我一下。
6. PNG文件预处理
aapt c[runch] [-v] -S resource-sources ... -C output-folder ... 做PNG文件的预处理,并将结果存储到一个文件夹中
实例: aapt c -S <res路径> -C <想存放的文件夹路径>
结果:
7.显示aapt版本
aapt v[ersion]
*******************************************************************cmd常用控制台
1、清屏命令:cls
2、列出当前目录详细信息:dir
3、删除文件:del xxx.txt
android adb常用命令
1.创建sdcard
mksdcard 50M D:/sdcard.img --> 创建一张容量为50M的SDCard
2.删除sdcard
cd d:/
del sdcard.img
3.把ljq.txt文件放在sdcard
adb push d:/ljq.txt /sdcard/
4.创建avd模拟器
android create avd -n avd名称 -t target平台编号
eg、android create avd -n android2.1 -t 8
说明:Error: Folder C:UsersAdministrator.androidavdljq.avd is in the way. Use --f
orce if you want to overwrite.(进入C:UsersAdministrator.androidavd目录,把ljq.avd文件夹删除即可)
5.启动模拟器
emulator -avd xxx
eg、emulator -avd android2.1
启动带sdcard模拟器
emulator -sdcard d:/sd.img -avd android2.1(android2.1之前创建好的一个虚拟设备的名称)
6.删除AVD(模拟器):
android delete avd -n name名称
eg、android delete avd -n android2.1
7.显示系统中全部android平台
android list targets
8.android list avd
9.adb devices
10.查看用户已安装的软件
adb shell
cd /data/app/
ls
11.安装软件
adb install d:abc.apk
12.卸载软件
adb shell
cd /data/app/
adb uninstall <软件名>
adb uninstall -k <软件名>
说明:如果加 -k 参数,为卸载软件但是保留配置和缓存文件. </B>
eg、adb uninstall com.ljq.activity
13.启动ddms:ddms
14.导出文件
adb pull adb pull <远程路径> <本地路径>
eg、adb pull /sdcard/hrtx/123.gif d:/
15.导入文件
adb push <本地路径> <远程路径>
eg、adb pull d:/123.gif /sdcard/
16.进入模拟器的shell模式:
adb shell
17.在命令行中查看LOG信息:
adb logcat
adb logcat -s 标签名
eg、adb logcat -s MainActivity
18.删除系统应用:
adb remount(重新挂载系统分区,使系统分区重新可写)
adb shell
cd /system/app
rm *.apk
19.获取管理员权限:
adb root
20.启动Activity
adb shell am start -n 包名/包名+类名(-n 类名,-a action,-d date,-m MIME-TYPE,-c category,-e 扩展数据,等)
eg、adb shell am start -n com.hrtx.activity/com.hrtx.activity.MainActivity
21.发布端口:
设置任意的端口号,做为主机向模拟器或设备的请求端口。
eg、adb forward tcp:5555 tcp:8000
22.查看bug报告:
adb bugreport
23.记录无线通讯日志:
一般来说,无线通讯的日志非常多,在运行时没必要去记录,但我们还是可以通过命令设置记录:
adb shell
logcat -b radio
24.获取设备的ID和序列号:
adb get-product
adb get-serialno
25.访问数据库SQLite3
adb shell
sqlite3
Android_AIDL
1. AIDL (Android Interface DefinitionLanguage )接口描述语言
2. AIDL 适用于 进程间通信,并且与Service端多个线程并发的情况,如果只是单个线程 可以使用 Messenger ,如果不需要IPC 可以使用Binder
3. AIDL语法:基础数据类型都可以适用,List Map等有限适用。static field 不适用。
要使用AIDL我们需要两个应用程序,一个作为Service端,一个作为Client端。详细步骤如下:
基本使用步骤:
第一步:在Service端建立.aidl文件。实际实现的接口是在 gen中自动生成的对应的抽象内部类 Stub。注意:
1、导入包名,不能在src目录下创建,否则在实现的时候找到Stub类。
2、如果有使用Object对象,需要该对象 implement Parcelable 接口,并且需要导入该接口包名+类名,如果是primitivetype 不需要这步。
3、定义方法名称。
4、所有的.aidl文件以及需要传递的对象接口需要在Service 与Client中各一份,并且包名要和服务器端的一样(建议从服务器端拷贝)。
示例代码:
package com.example.android_aidl_host.aidl;
interface IRemoteService{
int getId();
void setId(int id);
}
第二步:在Service中实现.aidl 接口(通常在service中实现)。
public class MyHostService extends Service{
privateint id;
@Override
publicIBinder onBind(Intent intent) {
//TODO Auto-generated method stub
returnbind;
}
privatefinal IRemoteService.Stub bind = new IRemoteService.Stub() {
@Override
publicint getId() throws RemoteException {
//TODO Auto-generated method stub
returnid;
}
@Override
publicvoid setId(int id) throws RemoteException {
//TODO Auto-generated method stub
MyHostService.this.id= id;
}
};
}
注意:在服务器端建立好service要在manifest文件中进行注册,并且为其加上action属性。我的配置如下:
<serviceandroid:name="com.example.android_aidl_host.MyHostService">
<intent-filter>
//其它程序通过此入口获得数据,就好比ContentProvider
<actionandroid:name="com.xz.apk"/>
</intent-filter>
</service>
经过以上两步服务器的代码就已经完成了,就等其它进程来获取数据了。下面来写Client端的代码。
第一步:在Activity中通过Intent意图绑定service。
Intent service = new Intent("com.xz.apk");//必须与服务器端一致
bindService(service, new MyConn(),BIND_AUTO_CREATE);
第二步:获取服务返回的stub对象。
iService = IRemoteService.Stub.asInterface(service);
完整的Activity代码如下:
public class MainActivity extends Activity {
//aidl文件生成的java文件名
IRemoteService iService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//绑定service
Intent service = new Intent("com.xz.apk");
bindService(service, new MyConn(),BIND_AUTO_CREATE);
}
public void changId(View view) {
switch (view.getId()) {
case R.id.set://客户端的set按钮
try {
//调用服务器端的setId()方法
iService.setId(200);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
case R.id.get: //客户端的get按钮
try {
//调用服务器端的getId()方法
iService.getId();
Log.e("DDDDD",iService.getId() + "");
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
break;
}
}
private class MyConn implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service){
//通过自动生成的Stub内部类,调用asInterface()方法实例化IRemoteService对象
iService =IRemoteService.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generatedmethod stub
}
}
}
Demo2:通过AIDL传递对象(Person),此实例既传递了普通数据又传递了对象。
1、定义该对象Person,并实现Parcelable。
2、添加Person.aidl文件,并采用如下方式编写导入Person
注意Person文件和Person.aidl文件必须放在同一个包中并且两者要同时存在,否则报错。
3、需要在引用到Person的.aidl文件中import+Person所在包名
4、需要在服务端和客户端都添加 Person.aidl与 Person.java文件并且需要一致。
Person类代码:
package com.example.android_aidl_mydemo_server.aidls;
import android.os.Parcel;
import android.os.Parcelable;
public class Person implements Parcelable {
String name;
int age;
//省略了相应的get和set方法
/**
* 在想要进行序列号传递的实体类内部一定要声明该常量。常量名只能是CREATOR,类型也必须是
* Parcelable.Creator<T>
*/
public static final Parcelable.Creator<Person>CREATOR = newParcelable.Creator<Person>() {
/***
* 根据序列号的Parcel对象,反序列号为原本的实体对象
* 读出顺序要和writeToParcel的写入顺序相同
*/
public Person createFromParcel(Parcel in) {
// String name =source.readString();
// int age =source.readInt();
// String sex =source.readString();
// Beauty beauty =new Beauty();
// beauty.setName(name);
// beauty.setAge(age);
// beauty.setSex(sex);
//
// returnbeauty;
return new Person(in);
}
/**
* 创建一个要序列号的实体类的数组,数组中存储的都设置为null
*/
public Person[] newArray(int size) {
return new Person[size];
}
};
public Person() { }
private Person(Parcel in) {
readFromParcel(in);
}
public int describeContents() {
return 0;
}
public void readFromParcel(Parcel in) {
age = in.readInt();
name = in.readString();
}
/**
* 将对象序列号dest 就是对象即将写入的目的对象 flags有关对象序列号的方式的标识
* 这里要注意,写入的顺序要和在createFromParcel方法中读出的顺序完全相同。例如这里先
* 写入的为name,
* 那么在createFromParcel就要先读name
*/
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(age);
dest.writeString(name);
}
}
Person.aidl文件:
packagecom.example.android_aidl_mydemo_server.aidls;
parcelable Person;
InData.aidl文件:
packagecom.example.android_aidl_mydemo_server.aidls;
import com.example.android_aidl_mydemo_server.aidls.Person;
interface InData{
String getName();
void setName(String name);
Person getPerson();
}
服务器端的service文件:
package com.example.android_aidl_mydemo_server;
import com.example.android_aidl_mydemo_server.aidls.InData;
import com.example.android_aidl_mydemo_server.aidls.Person;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
public class MyServer extends Service {
String name = "JACK";
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generatedmethod stub
returnbinder;
}
private final InData.Stub binder = new InData.Stub() {
@Override
public String getName()throws RemoteException {
// TODO Auto-generatedmethod stub
returnname;
}
@Override
public void setName(String name) throws RemoteException {
// TODO Auto-generatedmethod stub
MyServer.this.name = name;
}
@Override
publicPersongetPerson() throws RemoteException {
// TODO Auto-generatedmethod stub
Person person = new Person();
return person;
}
};
}
一说到service我又想起了一定不要忘记在manifest注册并加上action属性!
客户端MainActivity的代码:
package com.example.android_aidl_mydemo_client;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.Menu;
import com.example.android_aidl_mydemo_server.aidls.InData;
import com.example.android_aidl_mydemo_server.aidls.Person;
public class MainActivity extends Activity {
InData inData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intentservice=newIntent("com.ssss.xz.apk");
bindService(service, new MyConnection(),BIND_AUTO_CREATE);
}
private class MyConnection implements ServiceConnection{
@Override
public void onServiceConnected(ComponentName name, IBinder service){
// TODO Auto-generatedmethod stub
inData=InData.Stub.asInterface(service);
try {
Log.e("SSSSSS",inData.getName());
inData.setName("Hello AIDL");
Log.e("SSSSSS",inData.getName());
Person user=inData.getPerson();
Log.e("HHHHHHHH",user.getName());
Log.e("HHHHHHHH",user.getAge()+"");
} catch (RemoteException e) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generatedmethod stub
inData=null;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; thisadds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
*******************************************************************dx是将java的classes文件编译为字节码dex文件
dx --dex --output=<要生成的classes.dex路径> <要处理的类文件的路径>
dx --dex --output=D:/HelloWorld/bin/classes.dex D:/HelloWorld/bin
*******************************************************************android编译器生成的java class相关内容都放到了dex(.dex 是字节码文件,Dalvik VM上就运行的是.dex)文件中,为什么要反编译apk文件呢?
就目前来看Android开放度还很低,很多东西只有反编译官方的app才可以了解一些底层的东西。
对于软件开发人员来说,保护代码安全也是比较重要的因素之一,不过目前来说Google Android平台选择了Java Dalvik VM的方式使其程序很容易破解和被修改,
首先APK文件其实就是一个MIME为ZIP的压缩包,我们修改ZIP后缀名方式可以看到内部的文件结构,类似Sun JavaMe的Jar压缩格式一样,不过比较去别的是Android上的二进制代码被编译成为Dex
热心网友 时间:2022-04-30 11:41
1. add-ons 这里面保存着附加库,比如google Maps,如果安装了OPhone SDK,这里也会有一些类库在里面。热心网友 时间:2022-04-30 12:59
Android SDK 目录下有很多文件夹,主要都是干什么的呢? 1. add-ons 这里面保存着附加库,比如google Maps,当然你如果安装了OPhone SDK,这里也会有一些类库在里面。 2. docs 这里面是Android SDK API参考文档,所有的API都可以在这里查到。