aapt dump badging D:\ceshi.apk > D:/log.txt
aapt dump badging app-release.apk
adb logcat | findstr AppName >D:\log.txt
adb logcat | findstr com.riocento.taxrobot >D:\log.txt
OBB(文件格式) ,Opaque Binary Blob,文件格式,是安卓游戏通用数据包。在一些大型游戏上较为常见,同时还附以Data文件,亦或是md5.dat文件出现。通常在游戏开始前,程序会自动将obb解包至/sdcard/Android/data或者是/Android/obb目录下。但也有游戏不会解包,直接读取
查看Android手机的CPU架构类型: adb shell getprop ro.product.cpu.abi
现在市面上常见的CPU架构类型如下:
1、armeabiv-v7a: 第7代及以上的 32位ARM 处理器
2、arm64-v8a: 第8代、64位ARM处理器
3、armeabi: 第5代、第6代的32位ARM处理器,早期的手机在使用,现在基本很少了。
4、x86: Intel 32位处理器,在平板、模拟器用得比较多。
5、x86_64: Intel 64位处理器,在平板、模拟器用得比较多。
Unity->Android:
1.导出的Android项目会把Unity工程中使用到的jar,so整合在一起,Unity本身会生成jar和对应的so,第三方(项目开发者主动引用的jar和so)的不会改变,Export只是简单的Copy操作,意味着关注度低一些,在已有的Android项目中可以代替用到的第三方的jar和so
原文链接:https://blog.csdn.net/Wish1820/article/details/106683617/
2.本质是一个Activity,切换Scene都是在同一个Activity中切换界面。
3.Build ->Make Module 'xxx' 刚刚鼠标选的模块
Unity3d view(是一个OpenGLES的moudle,UnityPlayer是一个FrameLayout
注意点:
1.C#中的byte和Java中的byte取值范围不一样,Java中的取值范围为-128~127,C#中取值范围为0~255,所以不能直接进行转换
所以C#端使用SByte
2.Unity调用Java方法时,参数或者返回值最好是Byte或者Byte[]。
缺点是在Android平台容易造成Local Ref > 512的溢出Bug
局部引用溢出在Android不同版本上表现有所区别。
Android 8.0 之前局部引用表的上限是512个引用,Android 8.0后局部引用表上限提升到了8388608个引用,所以要测试溢出,需要注意系统版本。
Oracle Java 没有局部引用表上限限制,随着局部引用表不断增大,最终会出现OOM
把Unity打成Library给原生的使用:
有一些限制:
1.Unity as a Library supports rendering only full screen, rendering on a part of the screen isn’t supported.
2.Loading more than one instance of the Unity runtime isn’t supported.
3.You may need to adapt 3rd party Plug-ins (native or managed) to work properly
4.Overhead of having Unity in unloaded state is: 90Mb for Android and 110Mb for iOS
ADB相关:
adb logcat | findstr TestAndroidJavaProxy //命令行中打开logcat, TestAndroidJavaProxy为TAG
adb shell am : activity manager的缩写。这个命令可以启动Activity、打开或关闭进程、发送广播等操作
adb shell am <command> : 参考adb 打开和关闭应用_wang18323834864的博客-CSDN博客_adb 关闭应用
//使用Action方式打开系统设置-输入法设置
adb shell am start -a android.settings.INPUT_METHOD_SETTINGS
//使用组件名方式启动照相机功能
adb shell am start -n com.android.camera/.Camera
//打开拨号界面,并传递一个DATA_URI数据给拨号界面
am start -a android.intent.action.CALL -d tel:10086
startservice [options] <INTENT> : 根据Intent 启动Service
//使用ComponentName 方式启动一个Service
adb shell am startservice com.some.package.name/.YourServiceSubClassName
关闭指定包名的应用程序 : adb shell am force-stop com.some.package
杀死与应用程序的包名称相关联的所有进程。该命令只会杀死安全的进程,不会影响用户体验:
adb shell am kill com.some.package
杀死全部的后台进程 :adb shell am kill-all
JNI : Java Native Interface,即 Java本地接口. 作用 : 使得Java与本地其他类型语言(如C、C++)交互.
即在Java代码里调用 C、C++等语言的代码 或 C、C++代码调用Java代码.
//注:JNI是Java调用Native语言的一种特性; JNI是属于Java的,与Android 无直接关系
JNI中的常用对象和概念:
JNIEnv : Java的本地化环境,C/C++要访问java的类,对象,属性等等,都要通过它,包含了所有的API
JavaVM : Java虚拟机; 在一个进程里,可以创建多个JavaVM; 但对于Android比较特殊,规定了一个进程对应一个JavaVM(即每个app对应一个JavaVM)
JavaVM是用来获取JNIEnv,每一个Java线程对应一个JNIEnv
线程 : 不能跨线程访问JNIEnv,否则会crash
NDK : Native Development Kit,是 Android的一个工具开发包. 作用 : 快速开发C、 C++的动态库,并自动将so和应用一起打包成APK.
即可通过NDK在Android中使用JNI与本地代码(如C、C++)交互.
// 注: NDK是属于 Android 的,与Java并无直接关系.
为什么使用NDK来开发 :
1.性能方面(效率高,代码安全,很难被反编译);
2.功能方面(拓展性好,可方便地使用其他语言的开源库,不光是java,C/C++,还有其他的..);
3.使用方面(代码易于复用和移植)
有两种方式: 1. 利用自带的ndk-build; 2.利用cmake
JNI的一般流程 :
1.定义好本地的native方法(java端)
public native String getSignaturePassword();
2.javah命令生成xxx.h头文件(jdk10以后,javah命令合成在javac中了)
cd定位到上面创建的java文件的包的根目录下,执行命令:
javah -d ../jni -jni com.gmf.ndktest.NdkSimple
3.拷贝xxx.h、jni.h、jni_md.h这三个头文件到VS的工程目录,并添加依赖进来
//注: 1.jni.h和jni_md.h在jdk目录下搜索到的; 2.VS项目中要设置为动态链接库.dll, 且#include <>改为""
4.新创建*.c文件,并实现我们的头文件中的native方法;
5.生成 dll动态库
6.java中引入dll动态库, 并通过System.load("D:\\xxxxx.dll")即可
Native层的方法签名格式: Java_包名_类名_方法名 //其中包名的.用_代替
eg: Java_com_gmf_test_MainActivity_stringFromJNI
JNIEnv的实现原理
typedef const struct JNINativeInterface_ *JNIEnv;
是一个结构体指针的别名,其实就是一个一级指针; 通过在结构体里存有函数指针...
C/C++调用Java方法:
env-> / (*env)->
FindClass()
GetMethodID/GetFieldID()
NewObject()
Call<TYPE>Method / [G/S]et<Type>Field ()
//其中,需要用到Signature(签名),可在bin下查看: NDKTest\bin>javap -p -s com.gmf.ndktest.NdkSimple1
如java.lang.String: "Ljava/lang/String;"
JNIEnv里的主要方法:
//获取methodId
jmethodID j_mid = (*env)->GetStaticMethodID(env, jcls, "getUUID", "()Ljava/lang/String;");
//调用getUUID()方法 static
jstring j_str_uuid = (*env)->CallStaticObjectMethod(env, jcls, j_mid);
//打印字符串 jstring -> c_str
char* c_str_uuid = (*env)->GetStringUTFChars(env, j_str_uuid, NULL);
printf("c_uuid = %s", c_str_uuid);
基本的数据类型:
jstring -> java String
jint -> java int
jfloat -> java float
jdouble -> java double
jobject -> java object
void -> V
3.回收内存
//jstring -> c_str, 记得回收内存
(*env)->ReleaseStringUTFChars(env, j_str_uuid, c_str_uuid);
4.签名,记住,方法的签名 : (参数)返回值
public Point test(int x, float y)
(IF)Ljava/awt/Point; ##包名的.转为/
String -> Ljava/lang/String
Object[] -> [L全类名; ##数组类型为[, 注:没有右边的].
5.C层构建Java层的对象,并返回给java层
//获取point的class, name="全类名"
jclass point_clz = (*env)->FindClass(env, "com/gmf/ndktest/Point");
//构建java层的Point对象, 构造函数用<init>,
jmethodID j_mid = (*env)->GetMethodID(env, point_clz, "<init>", "(II)V");
jobject point = (*env)->NewObject(env, point_clz, j_mid, 11, 22);
return point;
Android共享内存 :
1.binder和socket通信的区别有哪些?
a).binder驱动比socket通信快,binder使用的是共享内存,socket使用的是拷贝内存,且拷贝了2次;
b).socket通信灵活些,既可用于低端的本机的通信,也可用于远端的
c).Android下大部分使用的是Binder通信.
2.Serializable 和 Parcelable 之间的区别
Serializable写文件,慢些,还要关闭流,开销大; Parcelable操作的是内存,就是共享内存,对象永远在内存里,更高效
3.Parcelable 序列化和反序列化的具体过程?
画图,怎么样把数据存到C里面,....