导航:首页 > 源码编译 > action编译apk

action编译apk

发布时间:2023-01-21 23:48:28

⑴ 如何反编译android应用并重新打包

一.看android的源代码 1)将Apkd.apk 用zip解压后,出现了一个classes.dex文件 2014/02/19 19:42 . 2014/02/19 19:42 .. 2014/02/19 15:35 1,656 AndroidManifest.xml 2014/02/19 15:35 687,024 classes.dex 2014/02/19 15:49 META-INF 2014/02/19 15:49 res 2014/02/19 15:35 2,200 resources.arsc 2)进入到dex2jar目录中,运行情况如下: D:\developer\tools\test_apk\dex2jar-0.0.9.15>dex2jar.bat "..\Apkd(d2j)\classes.d ex" this cmd is deprecated, use the d2j-dex2jar if possible dex2jar version: translator-0.0.9.15 dex2jar ..\Apkd(d2j)\classes.dex -> ..\Apkd(d2j)\classes_dex2jar.jar Done. 在apk所在的目录会出现 classes_dex2jar.jar 文件。 3) 用JD-GUI对jar包进行查看,可以查看源文件 二.反编译apk 1.在下载APKTOOL中的三个文件(aapt.exe、apktool.bat、apktool.jar)解压缩到你的Windows安装目录下,以方便使用Dos命令. 2012/12/06 11:44 854,016 aapt.exe 2014/02/19 17:15 277,372 Apkd.apk//示例用apk文件 2012/12/23 23:39 92 apktool.bat 2013/02/03 02:37 2,655,843 apktool.jar 2.进入到apktool.bat所在的目录,运行: apktool d Apkd.apk decode_dir 反编译后,decode_dir目录下的内容如下: 2014/02/19 17:16 716 AndroidManifest.xml 2014/02/19 17:16 237 apktool.yml 2014/02/19 17:18 build 2014/02/19 17:16 res 2014/02/19 17:16 smali 此时我可以查看原文件AndroidManifest.xml了,也是查看smali源文件(是用smali语言写的,可以对照java看)。 三.APKTOOL的使用 1).decode 该命令用于进行反编译apk文件,一般用法为 apktool d 代表了要反编译的apk文件的路径,最好写绝对路径,比如C:\MusicPlayer.apk 代表了反编译后的文件的存储位置,比如C:\MusicPlayer 如果你给定的已经存在,那么输入完该命令后会提示你,并且无法执行,需要你重新修改命令加入-f指令 apktool d –f 这样就会强行覆盖已经存在的文件 2).build 该命令用于编译修改好的文件,一般用法为 apktool b 这里的 就是刚才你反编译时输入的 (如C:\MusicPlayer),输入这行命令后,如果一切正常,你会发现C:\MusicPlayer内多了2个文件夹build和dist,其中分别存储着编译过程中逐个编译的文件以及最终打包的apk文件。 3).install-framework 该命令用于为APKTool安装特定的framework-res.apk文件,以方便进行反编译一些与ROM相互依赖的APK文件。具体情况请看常见问题 四.smali与java源码对照,并做出相应的修改 java源代码: import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.widget.*; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView a = (TextView)this.findViewById(R.id.test) ; a.setText("raoliang"); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } } 对应的smali源代码: .class public Lali/text/apkd/MainActivity; .super Landroid/app/Activity; .source "MainActivity.java" # direct methods .method public constructor ()V .locals 0 .prologue .line 8 invoke-direct {p0}, Landroid/app/Activity;->()V return-void .end method # virtual methods .method protected onCreate(Landroid/os/Bundle;)V .locals 2 .parameter "savedInstanceState" .prologue .line 12 invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V .line 13 const/high16 v1, 0x7f03 invoke-virtual {p0, v1}, Lali/text/apkd/MainActivity;->setContentView(I)V .line 14 const/high16 v1, 0x7f08 invoke-virtual {p0, v1}, Lali/text/apkd/MainActivity;->findViewById(I)Landroid/view/View; move-result-object v0 check-cast v0, Landroid/widget/TextView; .line 15 .local v0, a:Landroid/widget/TextView; const-string v1, "raoliang" invoke-virtual {v0, v1}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V .line 16 return-void .end method .method public onCreateOptionsMenu(Landroid/view/Menu;)Z .locals 2 .parameter "menu" .prologue .line 21 invoke-virtual {p0}, Lali/text/apkd/MainActivity;->getMenuInflater()Landroid/view/MenuInflater; move-result-object v0 const/high16 v1, 0x7f07 invoke-virtual {v0, v1, p1}, Landroid/view/MenuInflater;->inflate(ILandroid/view/Menu;)V .line 22 const/4 v0, 0x1 return v0 .end method 通过对比可以看到,常量是没有必变的,可以根据的smali的语法,进行相应的修改 五.3、打包、签名和安装修改后的apk 修改完了,就可以打包回apk了。执行以下命令: apktool b decode_dir 在mygame目录下的dist在会看到打包好的apk。 当然,现在一般是无法安装的,因为apk还没有签名。下面就来签名。签名需要keystore文件,我已经有专用的keystore了,如果还没有,请参阅这里进行生成。 执行以下命令为重新编译的my_game.apk签名: jarsigner -verbose -keystore demo.keystore Apkd.apk demo.keystore 最后,在安装到手机前,需要把手机中的已有版本先卸载,因为如果签名不同,是不能覆盖安装的,会提示“应用程序未安装”错误。 完整的运行情况如下: D:\developer\tools\test_apk\new\decode\dist>keytool -genkey -alias demo.keystore -keyalg RSA -validity 40000 -keystore demo.keystore 输入keystore密码: 再次输入新密码: 您的名字与姓氏是什么? [Unknown]: rao 您的组织单位名称是什么? [Unknown]: rao 您的组织名称是什么? [Unknown]: 您所在的城市或区域名称是什么? [Unknown]: 您所在的州或省份名称是什么? [Unknown]: 该单位的两字母国家代码是什么 [Unknown]: CN=rao, OU=rao, O=Unknown, L=Unknown, ST=Unknown, C=Unknown 正确吗? [否]: y 输入的主密码 (如果和 keystore 密码相同,按回车): D:\developer\tools\test_apk\new\decode\dist>jarsigner -verbose -keystore demo.keystore Apkd.apk demo.keystore 输入密钥库的口令短语: 正在添加: META-INF/MANIFEST.MF 正在添加: META-INF/DEMO_KEY.SF 正在添加: META-INF/DEMO_KEY.RSA 正在签名: res/drawable-hdpi/ic_launcher.png 正在签名: res/drawable-mdpi/ic_launcher.png 正在签名: res/drawable-xhdpi/ic_launcher.png 正在签名: res/drawable-xxhdpi/ic_launcher.png 正在签名: res/layout/activity_main.xml 正在签名: res/menu/main.xml 正在签名: AndroidManifest.xml 正在签名: classes.dex 正在签名: resources.arsc D:\developer\tools\test_apk\new\decode\dist> 到此为止,修改后的apk可以正常的安装了,不过,在安装之前,必须要先卸载以前的apk,不能直接替换(因为签名不一样)

⑵ unity 导出安卓工程怎么编译成apk

1.Android端代码可以在Eclipse中开发(AndroidStudio没有试,应该也可以)

2.Unity3D端代码要在Unity中开发

3.Android和Unity3D端,两边都需要加入一些代码从而可以使之关联交互。

4.将Android端代码编译成jar文件以插件形式放入到Unity端中

5.在Unity中将整个项目Build成apk文件,然后安装到手机或模拟器里运行

本文主要讲解1,2,3。对于4,5建议大家去看雨松MOMO的Unity博客的第17篇和第18篇。

UnityPlay:

在编写Android端和Unity3d端代码前,有必要先了解一下可以使两部分交互的类UnityPlay。

个人理解UnityPlay是个Unity提供给外部交互的一个接口类。

为什么是“个人理解”?这我不得不爆粗口了,TMD官网根本就没有相关的API和文档(如果大家有谁找到一定给我来一份,就当我骂自己了)。

在关联Android时,想拿到UnityPlay以及相关类的jar包可以从下面的地址找到:Unity安装路径\Editor\Data\PlaybackEngines\androidplayer\bin在bin文件夹下有一个classes.jar的jar文件,它就是我们想要的。

而在bin同目录下有一个src文件,点击到最后有3个类,分别是UnityPlayerActivity.java,UnityPlayerProxyActivity.java,UnityPlayerNativeActivity.java。前两个打开个后只有一行代码,说的是UnityPlayerActivity和UnityPlayerProxyActivity都继承自UnityPlayerNativeActivity。而打开UnityPlayerNativeActivity中居然有代码,而且我估计这应该是UnityPlayerNativeActivity的源码。

由于关于UnityPlay的资料我只找到这么一个,所以我把UnityPlayerNativeActivity中的代码都贴出来,如果我注解有不对的地方希望大家指正。

/**
* UnityPlayerActivity,UnityPlayerProxyActivity都继承自UnityPlayerNativeActivity
* 而UnityPlayerNativeActivity继承自NativeActivity
* 在该类里定义了一些和ANDROID生命周期相同的回调方法,留给自定义的Activity子类重写。
*/
public class UnityPlayerNativeActivity extends NativeActivity
{
//UnityPlayer的引用,并且我们不能改变这个引用变量的名字,它被native code所引用
protected UnityPlayer mUnityPlayer;

protected void onCreate (Bundle savedInstanceState)
{
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
// 设置显示窗口参数
getWindow().takeSurface(null);
setTheme(android.R.style.Theme_NoTitleBar_Fullscreen);
getWindow().setFormat(PixelFormat.RGB_565);

// 创建一个UnityPlayer对象,并赋值给全局的引用变量
mUnityPlayer = new UnityPlayer(this);
//为UnityPlayer设置一些参数
if (mUnityPlayer.getSettings ().getBoolean ("hide_status_bar", true))
getWindow ().setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);

int glesMode = mUnityPlayer.getSettings().getInt("gles_mode", 1);
boolean trueColor8888 = false;
// UnityPlayer.init()方法需要在将view附加到layout之前调用。它将会调用native code
mUnityPlayer.init(glesMode, trueColor8888);

// 从UnityPlayer中获取到Unity的View视图
View playerView = mUnityPlayer.getView();
// 将Unity视图加载到根视图上
setContentView(playerView);
// 使Unity视图获取焦点
playerView.requestFocus();
}
protected void onDestroy ()
{
// 当Activity结束的时候调用UnityPlayer.quit()方法,它会卸载之前调用的native code
mUnityPlayer.quit();
super.onDestroy();
}

// 下面几个方法都是ANDROID相关回调方法,确保在ANDROID执行相应方法时UnityPlayer也需调用相应方法
protected void onPause()
{
super.onPause();
mUnityPlayer.pause();
}
protected void onResume()
{
super.onResume();
mUnityPlayer.resume();
}

public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
mUnityPlayer.configurationChanged(newConfig);
}
public void onWindowFocusChanged(boolean hasFocus)
{
super.onWindowFocusChanged(hasFocus);
mUnityPlayer.windowFocusChanged(hasFocus);
}
public boolean dispatchKeyEvent(KeyEvent event)
{
if (event.getAction() == KeyEvent.ACTION_MULTIPLE)
return mUnityPlayer.onKeyMultiple(event.getKeyCode(), event.getRepeatCount(), event);
return super.dispatchKeyEvent(event);
}
}

⑶ 如何编译android launcher

注意前提条件是具备下面事项,需要系统级别的权限

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.rtkj.switchlauncher"
android:sharedUserId="android.uid.systemui"

<uses-permission android:name="android.permission.SET_PREFERRED_APPLICATIONS" />

可以导出Apk文件放到系统的system/app目录下面去编译

第一种方式 : 清理Launcher的默认设置的 默认值相当于在设置->应用程序->管理应用程序->所有应用程序列表,找到之前设置的
默认Launcher,并取消了默认值,系统会重新弹出launcher选择框。

private void clearDefaultValues(String packageName) {
getPackageManager().(packageName);

}

第二种方式: 通过pm进行 清理 后添加 或者是替换当前的 ,这里显示的是两个Launcher的替换

view plain

private void setDefaultHome(String packeageName ,String className,String oldPackage,String oldName) {
PackageManager pm = getPackageManager();
IntentFilter f = new IntentFilter();
f.addAction(Intent.ACTION_MAIN);
f.addCategory(Intent.CATEGORY_HOME);
f.addCategory(Intent.CATEGORY_DEFAULT);
ComponentName component = new ComponentName(packeageName,className );
ComponentName[] components = new ComponentName[] {new ComponentName(oldPackage,oldName),component};

<span style="color:#FF0000;">pm.(oldPackage);</span>// 清理配置的默认信息
pm.addPreferredActivity(f, IntentFilter.MATCH_CATEGORY_EMPTY, components, component);//添加
<span style="color:#FF0000;">//pm.replacePreferredActivity(f, IntentFilter.MATCH_CATEGORY_EMPTY, components, component);</span> //替换

}

view plain

//存在多个以上的Launcher的时候
private void setDefaultLauncher() {
// remove this activity from the package manager.
PackageManager pm = getPackageManager();

String examplePackageName = "com.jeejen.family"; //请修改为需要设置的 package name
String exampleActivityName = "com.jeejen.home.launcher.Launcher"; //请修改为需要设置的 launcher activity name

ComponentName defaultLauncher = null;
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);

List<ResolveInfo> resolveInfoList =
pm.queryIntentActivities(intent, 0);
if (resolveInfoList != null) {
int size = resolveInfoList.size();
for (int j = 0; j < size; ) {
final ResolveInfo r = resolveInfoList.get(j);
if (!r.activityInfo.packageName.equals(examplePackageName)) {
resolveInfoList.remove(j);
size -= 1;
} else {
j++;
}
}
ComponentName[] set = new ComponentName[size];
defaultLauncher = new ComponentName(examplePackageName, exampleActivityName);
int defaultMatch = 0;
for (int i = 0; i < size; i++) {
final ResolveInfo resolveInfo =
resolveInfoList.get(i);
set[i] = new ComponentName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name);
if (defaultLauncher.getClassName().equals(resolveInfo.activityInfo.name)) {
defaultMatch = resolveInfo.match;
}
}
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_MAIN);
filter.addCategory(Intent.CATEGORY_HOME);
filter.addCategory(Intent.CATEGORY_DEFAULT);

pm.(defaultLauncher.getPackageName());
pm.addPreferredActivity(filter, defaultMatch, set, defaultLauncher);
}
}

切换后启动当前的Launcher,
view plain

public void startMainLauncher(){
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
}

⑷ 怎样把反编译的apk文件在eclipse中打开

那要看你反编译的程度了。apk反编译有两部分,一部分是res等xml资源文件。用android 的apktool就可以了。这些xml文件都可以在eclipse中直接打开。
dex文件(源代码)需要使用dex2jar工具转化成jar文件。jar文件可以在eclipse查看其结构。对.class文件,eclipse可以查看方法,内部类等信息。
如果对Jar也进行了反编译,那么得到的就是Java文件。在eclipse中,可以像你new 的class一样查看。

⑸ APK包名修改 请问如何修改APK包名

基本过程如下:
1、将apk解包成一个文件夹
2、修改AndroidManifest.xml中对应的包名
3、修改smali目录下中的包
4、将文件夹打包成apk
5、将apk重新签名
6、验证apk的签名
7、优化apk
8、安装apk,并测试
基本前提条件:
1、java的环境
2、Eclipse及android的开发环境(这个主要是用来进行调试)
3、text文本编辑器,本人用的是UEdit,也可以用类似的,主要是利用其查找及替换功能
这篇文章主要用来反编译apk得到源码,但google进行了反制,只能得到一些可读性不高的源码,这里主要是利用反编译apk生成程序的源代码和图片、XML配置、语言资源等文件.
参考文献里提到的apktool-1.0.0.tar.bz2和apktool-install-windows-2.1_r01-1.zip均可以从http//code.google.com/p/android-apktool/上下载,下载好之后,将涉及的命令行目录及exe目录添加到电脑的path路径中,这样就便于操作了,如检测apktool是否可以,可以在命令行中输入apktool,如果可以识别就表示OK了。
参考了国内的技术文章后,有人发帖以上面的思路进行操作,但没有发技术文章,所以笔者只能去国外论坛中逛逛了,在Stack Overflow中,找到了相关的帖子,有老外留言"you can't do this",这个的确有违技术道德,但这里只做学习参考或交流。找到了一片帖子http://stackoverflow.com/questions/9218641/renaming-the-package-name-inside-an-apk,这篇帖子的回答给了比较详细的步骤(如上),他的情况比这个还稍微复杂点,简化后就是我要的结果,我就是按照这个基本步骤来的,回答的英文比较好懂(很有可能是国人)。
下面就按照上面的步骤一步步操作:我是已QQ浏览器4.0版的apk来操作的。
1、我的apktool安装到了E盘下的apktool目录下,所以的操作也在这个目录下进行 E:\apkTool
将apk复制到E:\apkTool目录下,重命名为qq4.0.apk(这个没有要求,随意就好)
将apk解包 命令行下cd到E:\apkTool这个目录 apktool d qq4.o.apk qq4 将apk解包到qq4(这个也可以随意)这个目录
E:\apkTool\qq4这个目录下内容如下:

2、修改AndroidManifest.xml中的包名,
将package后面的包名com.tencent.qbx改为你想要的新包名,我改为了com.tianxiao.tencentweb
将涉及原包名的com.tencent.qbx的相关activity的声明中的包名均改为新包名com.tianxiao.tencentweb
至于intent-filter里面的action名中包含原包名的,则可以不改,如果改的话,代码中也要相应的改变
另外,如果有provider,provider的authorities也得改,这个在同一手机上必须唯一,否则安装会失败
3、在E:\apkTool\qq4\smali目录下,有很多子目录,子目录下的文件多以smali结尾,这中文件的语法有点类似于汇编语言,具体原理就不深究了。
将smali目录下的所有文件中的原包名的声明形式com/tencent/qbx改为新包名com/tianxiao/tencentweb
具体如下,用UEdit在文件中替换即可,将目标目录指向E:\apkTool\qq4\smali,这个将近1000条左右
如果之前改为action里面的包名,也要将字符串形式的包名com.tencent.qbx改为com.tianxiao.tencentweb
如果有provider也要讲原来的authorities值改为在AndroidManifest.xml中新改的authorities值。
4、将E:\apkTool\qq4重新打包为apk
apktool b qq4 newqq.apk
5、将新的newqq.apk 重新签名
签名的方法很多,一主要是手动生成签名,用命令行签名
我采用的现成的,下载了一个Auto-sign的文件夹,进行了签名,这个比较简单,网上帖子很多,就不赘述。
新签名后的apk名为 newqq4signed.apk
6、验证签名 是否正确
jarsigner -verify -verbose -certs newqq4signed.apk
一般来说,没问题,略过
7、优化apk
zipalign -v 4 newqq4signed.apk latestqq.apk 优化过的apk名为latestqq.apk
8、安装新的apk,验证是否成功
这个最好把Eclipse打开,手机连上,查看logcat的安装信息。
我尝试了3次才成功,主要是忘了 provider的authorities的处理,
出错信息如下: Can't install because provider name qbx_bookmarks (in package com.tianxiao.tencentweb) is already used by com.tencent.qbx
原因很清楚,所以debug还是相当给力的,原来不喜欢debug,看debug过程可以更好的了解执行过程。

⑹ 如何在android 源码提取一个完整的apk

一、工具准备: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文件
1.用命令(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复制values\strings.xml 到 values-zh-rCN 并翻译.
2.2 去广告见;
3.重建APK,用命令(apktool b xxx) ,输出到ABC/dist/out.apk
或命令( apktool b xxx out.apk)
六、重新打包 和 签名

⑺ apk入口在哪里

android应用程序(apk)没有固定的入口点,系统会根据各个程序的manifest设定,在发生指定事件的时候调用程序的指定位置。
如果你说的入口点是传统上认为的main函数,那么在android应用程序里面,相对应的就是在manifest里面用intent-filter设定了会处理main action的那个activity。
(7)action编译apk扩展阅读:
APK(全称:Android application package,Android应用程序包)是Android操作系统使用的一种应用程序包文件格式,用于分发和安装移动应用及中间件。一个Android应用程序的代码想要在Android设备上运行,必须先进行编译,然后被打包成为一个被Android系统所能识别的文件才可以被运行,而这种能被Android系统识别并运行的文件格式便是“APK”。 一个APK文件内包含被编译的代码文件(.dex 文件),文件资源(resources), 原生资源文件(assets),证书(certificates),和清单文件(manifest file)。
APK 文件基于 ZIP 文件格式,它与JAR文件的构造方式相似,互联网媒体类型是:application/vnd.android.package-archive。
介绍
APK是Android application package的缩写,即Android安装包(apk)。APK是类似SymbianSis或Sisx的文件格式。通过将APK文件直接传到Android模拟器或Android手机中执行即可安装。[2]
apk文件和sis一样,把androidsdk编译的工程打包成一个安装程序文件,格式为apk。 APK文件其实是zip格式,但后缀名被修改为apk,通过UnZip解压后,可以看到Dex文件,Dex是DalvikVM executes的简称,即Android Dalvik执行程序,并非Java ME的字节码而是Dalvik字节码。Android在运行一个程序时首先需要UnZip,然后类似Symbian那样直接,但不同于Windows mobile中的PE文件,程序的保密性和可靠性不是很高,通过dexmp命令可以反编译它,但这种架构符合发展规律,微软的WindowsGadgets(WPF)也采用了这种架构方式。在Android平台中,dalvikvm的执行文件被打包为apk格式,最终运行时加载器会先解压,然后获取编译后的androidmanifest.xml文件中的permission声明对安全访问的限制,要知道仍然存在很多安全限制,但将apk文件传到/system/app文件夹下会发现执行是不受限制的。也许我们平时安装都不会选用这个文件夹,但在androidrom中,系统的apk文件默认会放入这个文件夹,它们拥有root权限。

阅读全文

与action编译apk相关的资料

热点内容
xlsx转换pdf 浏览:94
3dmax挤出命令英语 浏览:903
靶心率的定义和算法 浏览:513
3d模术师app哪里下载 浏览:474
php中文api文档 浏览:458
安卓设计怎么加入输入框 浏览:185
主根服务器什么时候开始 浏览:738
奇门遁甲完整版pdf 浏览:901
app软件怎么用的 浏览:802
电子书pdf购买 浏览:193
浪潮服务器如何做系统 浏览:111
冒险岛img格式加密 浏览:596
我的世界手游如何复制命令 浏览:659
天刀自动弹琴脚本源码 浏览:970
打开其它app微信怎么收不到 浏览:447
安卓游戏耳机怎么戴 浏览:18
不越狱怎么去除app广告 浏览:178
ipadminipdf阅读 浏览:506
文件夹无限制压缩会不会降低内存 浏览:412
荣耀怎样创建文件夹 浏览:631