android jni项目会删除第三方so文件的问题解决(jni project delete third-party .so file)

安卓项目开发中,项目中使用到jni开发,使用C/C++编写了自己的so库,调试和运行一切正常,Android.mk文件代码如下:

 

include $(CLEAR_VARS)

#opencv
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
OPENCV_LIB_TYPE:=SHARED
include ${OPENCVROOT}/sdk/native/jni/OpenCV.mk

LOCAL_LDLIBS += -llog
LOCAL_MODULE := xface
LOCAL_SRC_FILES := xface.cpp

 

如果我们需要引入其他第三方so库到libs/armeabi中时,在项目编译运行的时候会发现,刚刚加入的第三方so库,被删除了。

 

1、在jni中新建目录“prebuilt”
2、修改Android.mk文件,把我们的第三方so库加入进去,在我上面Android.mk增加后的内容如下:

include $(CLEAR_VARS)
LOCAL_MODULE := tpnsWatchdog
LOCAL_SRC_FILES := prebuilt/libmsc.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)

#opencv
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
OPENCV_LIB_TYPE:=SHARED
include ${OPENCVROOT}/sdk/native/jni/OpenCV.mk

LOCAL_LDLIBS += -llog
LOCAL_MODULE := xface
LOCAL_SRC_FILES := xface.cpp

错误: 找不到类org.opencv.core.Mat,jni Header Files with javah , show error that can’t find org.opencv.core.Mat

这个错误是我在搭建OPencv项目的时候遇到的:

一:这个时候我们可以去到项目的bin的classes目录下,按左边shift键,鼠标右键,在此处打开命令行

二:输入: javah -classpath (opencvandroid sdk 路径)/java/bin/classes;(你项目的的地址)/bin/classes -jni (输入你要的包地址接口名字)

注意在windows下两个路径之间的应该为“;”号,在其他系统linux和mac OS下为“:”

Javah 使用时报错:找不到类

使用JNI,在用javah生成头文件时,总是报错找不到类;

javah的命令行帮助:


用法:javah [选项] <类>

其中 [选项] 包括:

-help                                    输出此帮助消息并退出
-classpath <路径>                用于装入类的路径
-bootclasspath <路径>         用于装入引导类的路径
-d <目录>                             输出目录
-o <文件>                             输出文件(只能使用 -d 或 -o 中的一个)
-jni                                       生成 JNI样式的头文件(默认)
-version                               输出版本信息
-verbose                              启用详细输出
-force                                   始终写入输出文件

使用全限定名称指定 <类>(例如,java.lang.Object)

通用格式——javah -classpath . -jni 类路径.JNI类 在.和jni之间有空格

javah -classpath . -jni com.dagu.NdkTest.HelloOpenCV

 

LayoutParams继承于Android.View.ViewGroup.LayoutParams

LayoutParams相当于一个Layout的信息包,它封装了Layout的位置、高、宽等信息。假设在屏幕上一块区域是由一个Layout占领的,如果将一个View添加到一个Layout中,最好告诉Layout用户期望的布局方式,也就是将一个认可的layoutParams传递进去。
可以这样去形容LayoutParams,在象棋的棋盘上,每个棋子都占据一个位置,也就是每个棋子都有一个位置的信息,如这个棋子在4行4列,这里的“4行4列”就是棋子的LayoutParams。

但LayoutParams类也只是简单的描述了宽高,宽和高都可以设置成三种值:
 1,一个确定的值;
2,FILL_PARENT,即填满(和父容器一样大小);
3,WRAP_CONTENT,即包裹住组件就好。

JAVA中动态构建的布局,常常这样写:

setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));

上面这一句话其实是子对父的,也就是说,父布局下的子控件要设置这句话。

因为布局很多,虽然都继承至ViewGroup但是各个布局还是有很大的不同。

很显然上面这句应该这样写才算准确:

setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT,TableRow.LayoutParams.FILL_PARENT));

这表示这个子控件的父布局是一个TableRow , 这样的LayoutParams 太多,所以应明确指明。

 

下面分别说下两个常用到布局:

1. FrameLayout下动态设置子控件居中,动态用JAVA代码要这样实现:

FrameLayout.LayoutParams lytp = new FrameLayout.LayoutParams(80,LayoutParams.WRAP_CONTENT);
lytp .gravity = Gravity.CENTER;
btn.setLayoutParams(lytp);

2. RelativeLayout下动态设置子控件居中:

RelativeLayout.LayoutParams lp=new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); 
lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE); 
lp.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE); 
btn1.setLayoutParams(lp);

Android APP安装后不在桌面显示图标的应用场景举例和实现方法

为了在用户安装了子APK之后不至于让用户的桌面全是各种图标,体验太差且让程序的入口还能集中在主APK,只能想办法使用一些小技巧在桌面不显示这些图标。具体实现方式如下:

1、开发一个名为OpenNoIconAPP.apk的主APP,里面就一个按钮用于点击后打开子APP,核心跳转代码如下:

public void onClick(View view) {
    switch (view.getId()) {
    case R.id.btn_open_app:
         /*
         * Intent intent = getPackageManager().getLaunchIntentForPackage(
         * "com.example.noicontest"); if (intent != null) { //
         * startActivity(intent); } else { 
         * Toast.makeText(getApplicationContext(), "没有该子APP,请下载安装",
         * Toast.LENGTH_LONG).show(); }
         */

        Intent intent = new Intent();
        ComponentName cn = new ComponentName("com.example.noiconapp","com.example.noiconapp.MainActivity");
        intent.setComponent(cn);
        intent.setAction("android.intent.action.MAIN");
        try {
            startActivityForResult(intent, RESULT_OK);
        } catch (Exception e) {
            Toast.makeText(this, "没有该子APP,请下载安装",Toast.LENGTH_SHORT).show();
        }
        break;

    default:
        break;
    }
}

2、开发名为NoIconAPP.apk的子APP(用于主APP去打开),该APP主要实现在桌面不显示图标。其中要想不显示桌面图标只需修改AndroidManifest.xml文件即可。具体如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.noiconapp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
    android:minSdkVersion="14"
    android:targetSdkVersion="14" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.example.noiconapp.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <!-- 要想在桌面不显示图标,只需注释掉APP入口Activity中的下面这句即可,或者把下面的LAUNCHER改成DEFAULT也行 -->
            <!-- <category android:name="android.intent.category.LAUNCHER" /> -->
        </intent-filter>
    </activity>
</application>
</manifest>

3、上面的设置可以让桌面图标不显示的原因:

一般情况下,当我们的APK在被安装后,系统会自动创建我们的APK程序,系统Launcher(系统桌面应用程序)会自动检测系统已经安装的应用软件的包名,然后把这些APP的图标和名称解析出来后显示在应用程序列表里,一旦我们像上面那样设置不显示APK图标,则APK程序在运行后只会显示在“正在运行”的程序列表中,而不会在桌面上显示图标和名字。如果只是设置APP图标不可见而使用第一种方式(我注释的代码)打开APP是不会成功的,因为这样设置后,包名根本就没有加载到Launcher,所以通过 getPackageManager().getLaunchIntentForPackage()方法得到的Intent为null。

来自:

一个批量安装文件夹下(包括子目录下)全部的Android apk文件批处理脚本

在做android开发的时候,经常遇到需要安装很多apk文件,需要做很多重复性的工作,这对于一名程序员来说是不可以容忍的。面对这种情况,就编写了一个批处理脚本实现自动化安装apk文件。
脚本如下,在使用前修改下apk文件的放置路径,在DOS下执行即可。源码如下所示:
  1. @echo off
  2. title ADB Install Apks[By LongLuo]
  3. goto BEGIN
  4. :COMMENT
  5. echo ##############################################
  6. rem     adb_install_apks.bat
  7. rem         By Long.Luo @2013/03/20
  8. rem
  9. rem     Description:
  10. rem         Used to install all the apks in a PATH including
  11. rem     the subdirs.
  12. rem
  13. rem     Version: 2.2
  14. rem
  15. echo ##############################################
  16. pause
  17. :BEGIN
  18. echo.
  19. echo ################   开始…    ################
  20. goto MAIN
  21. :MAIN
  22. rem search all the apks in the PATH.
  23. rem 首先请设置需要安装的apk文件所在的路径,
  24. rem 程序会自动搜索该文件夹(包括子目录)下的所有的apk文件,
  25. set work_path=F:\Android\MyApks
  26. cd /d %work_path%
  27. for /R %%s in (*.apk) do (
  28. echo 正在安装 %%s
  29. adb install -r “%%s”
  30. )
  31. :End
  32. echo.
  33. echo ################  全部apk文件已安装!   ################
  34. pause

脚本发出来之后,有同事提出能不能直接放在某个文件夹下面,直接执行脚本,毕竟去更改文件夹路径相对来说有点麻烦,于是完成了v2.3版本:

  1. @echo off
  2. title ADB Install Apks[By LongLuo]
  3. goto BEGIN
  4. :COMMENT
  5. echo ##############################################
  6. rem     adb_install_apks.bat
  7. rem         By Long.Luo @2013/03/20
  8. rem
  9. rem     Description:
  10. rem         Used to install all the apks in a PATH including
  11. rem     the subdirs.
  12. rem
  13. rem     Version: 2.3
  14. rem
  15. echo ##############################################
  16. pause
  17. :BEGIN
  18. echo.
  19. echo ################   开始…    ################
  20. goto MAIN
  21. :MAIN
  22. rem search all the apks in the PATH.
  23. rem 首先请设置需要安装的apk文件所在的路径,
  24. rem 程序会自动搜索该文件夹(包括子目录)下的所有的apk文件,
  25. for /R %%s in (*.apk) do (
  26. echo 正在安装 %%s
  27. adb install -r “%%s”
  28. )
  29. :End
  30. echo.
  31. echo ################  全部apk文件已安装!   ################
  32. pause
v2.3版本体验仍然不是很好,可不可以在执行的过程中自行输入文件夹路径呢?
于是完成了v2.4版本:
  1. @echo off
  2. title ADB Install Apks[By LongLuo]
  3. goto BEGIN
  4. :COMMENT
  5. echo ##############################################
  6. rem     adb_install_apks.bat
  7. rem         By Long.Luo @2013/03/20
  8. rem
  9. rem     Description:
  10. rem         Used to install all the apks in a PATH including
  11. rem     the subdirs.
  12. rem
  13. rem     Version: 2.4
  14. rem
  15. echo ##############################################
  16. pause
  17. :BEGIN
  18. echo.
  19. echo ################   开始…    ################
  20. goto MAIN
  21. :MAIN
  22. rem search all the apks in the PATH.
  23. rem 首先请设置需要安装的apk文件所在的路径,
  24. rem 程序会自动搜索该文件夹(包括子目录)下的所有的apk文件,
  25. set /p apk_path=请输入apk文件所在文件夹:
  26. cd /d %apk_path%
  27. for /R %%s in (*.apk) do (
  28. echo 正在安装 %%s
  29. adb install -r “%%s”
  30. )
  31. :End
  32. echo.
  33. echo ################  全部apk文件已安装!   ################
  34. pause
但是对于一个文件夹下面的apk文件,不是全部的apk文件都需要安装,可不可以将需要安装的apk文件拖动到脚本上来实现安装呢?
当然可以,于是完成了v2.5版本:
  1. @echo off
  2. title ADB Install Apks[By LongLuo]
  3. goto BEGIN
  4. :COMMENT
  5. echo ##############################################
  6. rem     adb_install_apks.bat
  7. rem         By Long.Luo @2013/03/20
  8. rem
  9. rem     Description:
  10. rem         Used to install all the apks in a PATH including
  11. rem     the subdirs.
  12. rem
  13. rem     Version: 2.5
  14. rem
  15. echo ##############################################
  16. pause
  17. :BEGIN
  18. echo.
  19. echo ################   开始…    ################
  20. :HELP
  21. rem 无文件拖至bat时
  22. if “%~1″==”” echo 请将apk直接拖放至bat文件!&goto END
  23. echo 注意事项:
  24. echo 支持多apk文件安装,即选中所有你要安装的apk拖动至此bat上!
  25. :MAIN
  26. setlocal enabledelayedexpansion
  27. if not “%~1″==”” (
  28.   echo.
  29.   rem 文件后缀名判断
  30.   if /i “%~x1″==”.apk” (
  31.     echo 安装”%~1″…
  32.     adb install -r “%~1”
  33.   ) else (
  34.     echo 文件类型错误:不支持%~x1!
  35.   )
  36.   shift /1
  37.   goto MAIN
  38. )
  39. :END
  40. echo.
  41. echo ################  全部apk文件已安装!   ################
  42. pause
以上。

2015目标

生活上:

  1. 购买一台MacBookPro电脑;
  2. 每周坚持运动,60天为一个周期,改变自己;
  3. 多点出去外面走走,力争去两个地方旅游(虽然旅游有点累,多走走也是不错的);

工作上:

  1. 尽量把手上的工作完成。

学习上:

  1. 希望可以继续在android的学习上更进一步,尤其是在UI方面的设计;
  2. 开发两个不错的app
  3. 尽可能的往游戏方面发展
  4. 接触一下ios的开发

(暂时先按自己的步骤来,一步一个脚印)