android:小问题汇总

1、将eclipse工程导入到android studio后的配置。

  Error: Your project contains C++ files but it is not using a supported native build system.

  在app模块的build.grade中的BuildTypes中加上sourceSets{ main{jni.src.Dirs=[ ] } } 

  1.1、工作电脑gradle版本为3.1.2,gradle插件版本为4.4,新建activity什么都没做也会报错,是因为默认配置不对。

    需要修改support库和SDK版本。support库和sdk一般还具有相关性,

    根据eventlog的信息找到出错的代码段落,把鼠标放到报错标注的部分,as会提示为什么以及怎么改。

2、使用ndk生成.so文件的步骤。

  首先需要安装ndk,在AS界面右上角的SDK  manager中给NDK打个勾就行了。

  然后设置一下jni文件夹下的两个mk文件

  在app模块的build.grade中的BuildTypes中加上sourceSets{ main{ jniLibs.srcDirs = ['src/main/jniLibs']     jni.srcDirs=[ ]  } }

  然后在terminal终端进入到jni所在的文件夹(cd  appsrcmainjni )后,输入ndk-build,就可以自动创建了so文件了。

  (没有设置环境变量则输入ndk-build所在文件夹:C:UsersccaesAppDataLocalAndroidSdk dk-bundle dk-build)

sourceSets{
     main{
        jni.srcDirs=[]
        jniLibs.srcDirs = ['src/main/jniLibs']
     }
}

/*jni.srcDirs=[] 是告诉ndk,jni源文件所在的目录,填了地址反而报错,还不如不填*/
/* jniLibs.srcDirs  是告诉app,so库所在的位置;那个jniLibs的文件夹名是可以修改的*/

   2.1 Android studio JNI中快速生成头文件  https://blog.csdn.net/wwdlss/article/details/80484140

    File->Setting->Tools->External Tools->Add External Tools。/**/Program: javah    /**/Parameters: -v -jni -d $ModuleFileDir$/src/main/jni $FileClass$ /**/  Working directory: $SourcepathEntry$  

3、如何设置定制机的APP签名

  3.1下图是如果签名不正确,或者没有签名会报的错误:

  Failed to finalize session : INSTALL_PARSE_FAILED_NO_CERTIFICATES: Package /data/app/vmdl540410799.tmp/0_dependencies has mismatched certificates at entry AndroidManifest.xml

  

  3.2解决前提:已有.keystore文件、key store password、key alias、key password

  解决步骤:build→generate signed apk→记得勾选两个按钮,点击完成之后会自动编译

       →project structure→app→signing中信息填写→buildtypes框框中signing config选上刚设置的签名。

4、关于Activity.finish()、Activity.onDestory()、System.exit(0)

  4.1、finish() 功能等价于back按键,结束当前acticity,但是并没有释放activity内存资源;

  4.2、onDestory() 结束当前activity且释放内存资源;

  4.3、System.exit(0) 结束当前应用程序且释放内存资源;

5、用drawable绘制btn的自定义xml时,右键drawable文件夹,new一个新的drawable resource file时并不会弹出selector的小框,而是弹出大框格New Resource File。

  不知道为什么会这样,但是我们可以换种方式来新建一个selector的xml文件。

  在res层右键,new一个Andrioid Resource File,然后在弹出框格中将resource type选为drawable,再给file取个名字,就会生成一个seletor的.xml了。

  然后下一次绘制btn的自定义xml的时候,又可以直接通过右键new一个新的selecotr或者shape、layer-list了。

6、使用MDK生成bin文件的目录,教程:https://blog.csdn.net/nx505j/article/details/80924902路径复制:

D:MDK5SetupFileARMARMCCinfromelf.exe --bin -o E:msOS_ZDWX_20190516KeilOutputLPC1114_PSAM.bin E:msOS_ZDWX_20190516KeilOutputmsOS.axf

7、android studio环境变量的配置:https://www.jianshu.com/p/c3e1fe6f61c4

8 使用TCP协议连接安卓adb;

  开启:https://www.cnblogs.com/clovershell/p/10684053.html

  more than one device connect : https://blog.csdn.net/yuemingxingxing/article/details/86590989

ps1:这是一篇让你少走弯路的 JNI/NDK 实例教程  https://blog.csdn.net/kisty_yao/article/details/79466396

ps2:Android NDK 视频https://www.youtube.com/watch?v=BWLOas4nojY

ps3:使用Stacktrace处理异常(这里是各种举例)  https://blog.csdn.net/u012585964/article/details/51772622

ps4:彻底解决unable to find valid certification path to requested target   https://blog.csdn.net/gabriel576282253/article/details/81531746

/*****android:JNI一些相关*******************************************************************************************************************************************************/

1 在JNI层使用log日志

  在c文件中加入下列宏定义;

#include "android/log.h"

#define TAG " JNI_LOG_TEST "
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)

#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG ,__VA_ARGS__) // 定义LOGI类型
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG ,__VA_ARGS__) // 定义LOGW类型
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG ,__VA_ARGS__) // 定义LOGE类型
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,TAG ,__VA_ARGS__) // 定义LOGF类型

LOGD("
 mode85: %d",mode85);    /*调用方式为:LOGD("zhe li shi zi fu %d",10 );*/

  在mk文件中加上下列代码,表示需要使用log;

 LOCAL_LDLIBS :=-llog

 2 JNI层的一些格式

  2.1 app层经常需要和jni层交换数据,java中的基本数据类型和JNI中的基本数据类型可能编译器的处理方式是相同的,所以可以直接传递调用;

    对于数组对象,编译器的处理方式可能不同,不能直接传递,可以借GetByteArrayElements函数来传递:

/*params:    jparray:复制的writeArray的地址,   jlen:writeArray的长度;*/
  JNIEXPORT jboolean JNICALL Java_XXX_spiWrite (JNIEnv *env, jclass object, jbyteArray writeArray)
  {
    jbyte *jparray = (*env)->GetByteArrayElements(env,writeArray, NULL); 
    jint jlen = (*env)->GetArrayLength(writeArray);
    
    jbyte jbuf[jlen];
    for(jint i=0; i<jlen; i++)  /*把数据从writeArray数组搬运到了JNI的数组jbuf[]里;*/
    {
        jbuf[i] = jparray[i];
    }    
    (*env)->ReleaseByteArrayElements(env,writeArray, jparray, 0); /*搬完释放线程?? */

    jbyteArray jpnewArray = env->NewByteArray(jlen);              /*这两行是回调相关函数,用来给jni回显数据到android层,放在这里不适合的*/
    env->SetByteArrayRegion(jpnewArray, 0, jlen, jbuf); 
    return ;
    }
/*app层是用户空间,linux是内核空间,那么这些定义在jni的数据是兼而有之吗?*/ 

   2.2 如果是C程序,要用 (*env)->   ;如果是C++要用 env->    ;

    在linux下如果.c文件中用 “env->” 编译会找不到此结构,必须用“(*env)->”

3 android端查看手机是否有root权限的代码;

    /*查看手机是否有root权限;代码开始:*/
    private final static String TAG = "RootUtil";

    public static boolean isRoot() {
        String binPath = "/system/bin/su";
        String xBinPath = "/system/xbin/su";
        if (new File(binPath).exists() && isExecutable(binPath))
            return true;
        if (new File(xBinPath).exists() && isExecutable(xBinPath))
            return true;
        return false;
    }

    private static boolean isExecutable(String filePath) {
        Process p = null;
        try {
            p = Runtime.getRuntime().exec("ls -l " + filePath);
            // 获取返回内容
            BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String str = in.readLine();
            Log.i(TAG, str);
            if (str != null && str.length() >= 4) {
                char flag = str.charAt(3);
                if (flag == 's' || flag == 'x')
                    return true;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (p != null) {
                p.destroy();
            }
        }
        return false;
    }
    /*查看手机是否有root权限;代码结束;*/

4 在jni层将android端打开的文件映射到内核打开的文件;

  大概就是说在android中,打开文件需要使用FileDescriptor类来打开文件;

  而在内核中使用open函数来打开文件,返回该文件的唯一性标识符fd;

  然后该网页提供的代码参考就是将这两端打开的文件对应起来,用来表示同一个文件;

  https://blog.csdn.net/shell812/article/details/49763195?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

原文地址:https://www.cnblogs.com/caesura-k/p/11694715.html