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下为“:”

2015 马上过去,2016需要给自己一个总结

2016新年,只是约定成俗的时间,不过既然来到了这个时间点,必须给自己过去一年的总结!

看了年初自己写的一篇博文,发现自己所希望的目标都已经差不多完成。先来回顾一下

①:买了自己的人生的第一台的RMBP开始进入了一个新的世界。

②:完成两个不错的游戏:自己做的游戏在自己的努力下~也在各大应用商店上市,也累计了一些用户,也有一些广告收入

③:去其他地方旅游,由于工作的原因~也出去外面不少的地方,青岛的大虾,莫言的故乡,上海的外滩,还有一些其他不为人知~却又出色的美景。各处不同的风土人情都让我记忆犹新。不过可以停留在在那里实在的游賞的时间很少!

④:要坚持做运动,这个坚持了大概一个月就因为工作加班太累而停下来~导致腹肌还是一块,这个要改啊!说好的6快腹肌还需努力!

⑤:技术方面,接触了iOS开发~刚刚开始接触,发现里面有很多的路要走,android开发感觉还要夯实,对于更多的引擎,只是了解了Libgdx,Unity3D,Cocos2D,,用了Lidgdx做了游戏。感觉引擎确实好用!,学习了各种开源的项目~对于OpenCV,ROS操作系统都有了一些了解!

工作感想,作为一名员工~天天加班,不停的工作,任劳任怨,希望在为公司付出的同时,得到自己的回报。

2016预想

①:首先是技术上~继续向android进发,了解多一点底层的技术。iOS开发出一个应用或游戏进入苹果应用商店,做出属于自己的自住导航方面的机器应用。最后要学习服务器端的搭建,不管是移动端的搭配还是Pc端的搭配,都要熟悉!

②还有就是广告收入方面,要做到每月500美刀,了解Apple的内购,和Admob的各种广告形式!

③:还有就是旅游了~争取去一趟西藏,洗涤一下心灵!或者去东北看看雪!

④:就是找到自己的位置吧,选择一个合适我发展的地方!

一年365天过的真的很快,希望在明天

mczha记于2016-1-1去深圳的路上

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

 

Android NDK开发环境搭建和常见问题解决办法

******************* 第一部分:Android NDK开发环境搭建(Windows) ***************

1.   配置Java环境

Android开发是需要Java环境的,所以需要先配置Java环境

(1)    JDK 7 官方下载地址:

http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html

如果windows系统是32位的话选择windows x86,64位的话选择windows x64

(2)    下载之后点击安装,路径可以保持默认,也可以自行修改 (笔者是 G:\java\jdk)

安装完了JDK之后,默认会提示继续安装JRE (笔者是 G:\java\jre)

(3)    配置环境变量

进入 我的电脑->属性->高级->环境变量->系统变量 中添加以下环境变量

JAVA_HOME:G:\java\jdk  (对应安装的JDK目录)

PATH:添加 %JAVA_HOME%\bin (这样做可以直接在DOS中调用bin目录下的可执行程序)

(4)    测试Java环境,进入命令提示符,输入 java –version,若成功返回JRE版本的话说明环境配置成功

1
2
3
4
5
6
7
$ java -version
                       
java version "1.7.0_25"
                       
Java(TM) SE Runtime Environment (build 1.7.0_25-b17)
                       
Java HotSpot(TM) Client VM (build 23.25-b01, mixed mode)

2.   安装ADT-Bundle

ADT-Bundle是集合了Android开发工具和Android SDK的开发工具包

(1)    资源地址:

官网下载地址:

https://developer.android.com/sdk/index.html

备用下载地址:

http://www.cnblogs.com/bjzhanghao/archive/2012/11/14/android-platform-sdk-download-mirror.html

(2)    下载之后解压即可

笔者解压位置: G:\android\adt-bundle

Android开发工具在其下的 eclipse 目录,这个开发工具叫做ADT(Android Development Tool),它默认包含了JDT,CDT,GEF,WTP以及ADT等优秀的插件,是一个极其精简的Android开发工具。

Android SDK在其下的 sdk 目录,现在(笔者写作的时间2013/8/26)下载安装的话默认只有android-4.2(API 17)这个平台。

(3)    测试ADT-Bundle工具

直接双击eclipse目录下的eclipse.exe,如果正常启动的话说明ADT工具可用,否则Java环境配置有误或者ADT工具有错。启动时需要配置一个工作空间,可以随便设置为一个已存在的文件夹,笔者是 G:\android\andrioiworkspace。

(4)    配置环境变量

进入 我的电脑->属性->高级->环境变量->系统变量 中添加以下环境变量

ANDROID_SDK:G:\android\adt-bundle\sdk

PATH:添加 %ANDROID_SDK%\tools;%ANDROID_SDK%\platform-tools

(5)    测试环境,进入DOS输入adb,如果正确输入adb版本则环境配置成功

$ adb version

Android Debug Bridge version 1.0.31

 

3.   安装Android NDK

NDK是Android进行一些底层相关开发的工具集

(1)    资源下载地址:

官方下载地址:

https://developer.android.com/tools/sdk/ndk/index.html

备用下载地址:

http://download.csdn.net/download/xiao87651234/3991166

(2)    下载之后解压即可

笔者解压位置:G:\android\android-ndk-r7

(3)    配置环境变量

进入 我的电脑->属性->高级->环境变量->系统变量 中添加以下环境变量

ANDROID_NDK:G:\android\android-ndk-r7

PATH:添加 %ANDROID_NDK%

(4)      测试环境,进入DOS输入ndk-build –v,如果输出类似的信息不是ndk-build命令找不到的话就表示环境配置成功,ndk-build命令其实是make命令的封装,所以打印出的信息是GNU Make的信息,下面是在DOS中的输出信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
GNU Make 3.81
                         
Copyright (C) 2006  Free Software Foundation, Inc.
                         
This is free software; see the source for copying conditions.
                         
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
                         
PARTICULAR PURPOSE.
                         
                          
                         
This program built for i586-pc-mingw32

 

如果安装了Cygwin,下面是在Cygwin中执行ndk-build -v的输出信息,从中可以看出Cygwin使用的不是系统中默认的GNU Make 3.81

1
2
3
4
5
6
7
8
9
10
11
12
13
$ ndk-build -v
                          
GNU Make 3.82.90
                          
Built for i686-pc-cygwin
                          
Copyright (C) 2010  Free Software Foundation, Inc.
                          
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
                          
This is free software: you are free to change and redistribute it.
                          
There is NO WARRANTY, to the extent permitted by law.

 

4.   安装Cygwin

Cygwin是一个在windows平台提供类似Linux操作的工具

(1)    Cygwin的官网地址:http://www.cygwin.com/

(2)    下载地址:http://www.cygwin.com/

(3)    安装教程:需要注意的是,建议安装的时候选择安装 Devel 下的所有工具

http://www.programarts.com/cfree_ch/doc/help/UsingCF/CompilerSupport/Cygwin/Cygwin1.htm

笔者的安装位置: G:\software\cygwin

 

5.   配置ADT开发工具

(1)    运行ADT(adt-bundle解压目录下的eclipse目录中的eclipse.exe程序),打开 Window -> Preferences -> Android,在右侧的SDK Location中填入Android SDK的目录,笔者是G:\android\adt-bundle\sdk,点击Apply,即可看到安装的Android Platforms。

(2)    切换到Android下的NDK,配置NDK Location为Android NDK目录,笔者的位置为G:\android\android-ndk-r7。

(3)    为了提高编写代码的速度,找到左侧Java下的Editor中的Content Assist,在Auto activation triggers for Java中添加26个英文字母,这样,在编写Java代码时任何一个字母被按下的话都会出现智能代码提示。

 

****************************  第二部分:常见问题及解决办法  *************************

1.       使用Android SDK Manager下载Android SDK Source失败

修改hosts文件:C:\Windows\System32\drivers\etc

增加如下一行配置:74.125.237.1 dl-ssl.google.com

2.       Tab出现提示“POWER RESET or UNKNOWN UPLOAD MODE”的解决方案

如果Tab出现一个界面显示“POWER RESET or UNKNOWN UPLOAD MODE”,其中还显示了一个Android机器人的话,说明tab进入了recovery 模式,要从中跳出来可以按下音量减小键+Home键+电源键,进入一个选择界面,根据提示按下音量减小键取消操作。

参考网址:

http://www.askmefast.com/How_do_i_repair_galaxy_sl_if_it_shows_power_reset_or_unknown_upload_mode-qna3987847.html#q3585028

3.       使用ndk-build命令报错:Android NDK: Host ‘awk’ tool is outdated. Please define HOST_AWK to point to Gawk or Nawk !

意思是NDK中的awk工具过时了,需要定义HOST_AWK为Gawk或者Nawk

解决办法:删除%ANDROID_NDK%\prebuilt\windows\bin\awk.exe即可,默认情况下它会使用Cygwin自带的awk工具

参考网址:

http://blog.csdn.net/achellies/article/details/7531440

4.       Android.mk文件中关于OpenCV的问题总结

如果不添加OPENCV_INSTALL_MODULES=on的话make会报错,提示cvLoadImage引用不存在,make失败

 

1
2
3
4
5
6
7
Compile++ thumb  : ndkdemo <= com_example_ndkdemo_NativeClass.cpp
                             
SharedLibrary  : libndkdemo.so
                             
G:/android/androidworkspace/ndkdemo/obj/local/armeabi-v7a/objs/ndkdemo/com_example_ndkdemo_NativeClass.o: In function `Java_com_example_ndkdemo_NativeClass_cvImage':
                             
G:/android/androidworkspace/ndkdemo/jni/com_example_ndkdemo_NativeClass.cpp:125: undefined reference to `cvLoadImage'

 

如果将OPENCV_LIB_TYPE=STATIC也会报错,内容很多,有些是如下所示,大致意思就是说链接静态库的时候失败,无法合并文件的指定目标数据

 

1
2
3
4
5
SharedLibrary  : libndkdemo.so
                               
G:/android/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld.exe: G:/android/androidworkspace/ndkdemo/obj/local/armeabi-v7a/libopencv_highgui.a(loadsave.cpp.o): Unknown mandatory EABI object attribute 44
                               
G:/android/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld.exe: failed to merge target specific data of file G:/android/androidworkspace/ndkdemo/obj/local/armeabi-v7a/libopencv_highgui.a(loadsave.cpp.o)

如果设置为OPENCV_INSTALL_MODULES=on 和 OPENCV_LIB_TYPE=STATIC的话,ndk-build不会出错,正常得到libopencv_java.so和libtarget.so,但是运行的时候报错,而libopencv_java.so明明就在libs目录下,甚至生成的APK文件中同样存在!

dlopen(“/data/app-lib/com.example.ndkdemo-2/libndkdemo.so”) failed: Cannot load library: soinfo_link_image(linker.cpp:1635): could not load library “libopencv_java.so” needed by “libndkdemo.so”; caused by load_library(linker.cpp:745): library “libopencv_java.so” not found

错误的原因其实很简单,libopencv_java作为一个动态库,和项目中的另一个动态库(这里是libndkdemo.so)一样,虽然libndkdemo.so依赖libopencv_java.so,但是并不会那么聪明地去加载,而应该显示在代码中提前加载libopencv_java.so

static{

System.loadLibrary(“opencv_java”);

System.loadLibrary(“ndkdemo”);

}

相关问题参考网址:[注意,问题的解决办法并不是添加opencv的library项目]

http://stackoverflow.com/questions/10894379/opencv-2-4-1-unsatisfiedlinkerror?rq=1

http://docs.opencv.org/doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.html#application-development-with-static-initialization

5.       ndk-build编译报错,问题涉及大量STL库中的类

在Cygwin下进行ndk-build,如果发现出现了很多的问题,可能很多问题都不是自己代码里的,这个时候要考虑是否缺少了其他的lib!例如看到很多vector出错(出错原因可能是No Such File or Directory),这说明stl库没有引入,那么需要在Application.mk中添加APP_STL := gnustl_static

6.       ndk-build编译的过程中,如果出现undefined reference *** 的错误

例如下面:

1
2
3
4
5
6
7
8
9
10
11
G:/android/androidworkspace/DemoCamera/obj/local/x86/objs/gaze/com_example_democamera_GazeLibrary.o: In function `Java_com_example_democamera_GazeLibrary_destroy':
                                 
G:/android/androidworkspace/DemoCamera/jni/com_example_democamera_GazeLibrary.cpp:85: undefined reference to `Destroy()'
                                 
G:/android/androidworkspace/DemoCamera/obj/local/x86/objs/gaze/com_example_democamera_GazeLibrary.o: In function `Java_com_example_democamera_GazeLibrary_initial':
                                 
G:/android/androidworkspace/DemoCamera/jni/com_example_democamera_GazeLibrary.cpp:39: undefined reference to `Initial()'
                                 
collect2: ld returned 1 exit status
                                 
/cygdrive/g/android/android-ndk-r7/build/core/build-binary.mk:312: recipe for target `/cygdrive/g/android/androidworkspace/DemoCamera/obj/local/x86/libgaze.so' failed

需要注意的是Android.mk文件中的LOCAL_SRC_FILES的配置,编译的过程中是按照给定的顺序一个一个进行编译的,所以这个顺序是有要求的,不能随便给定,如果a.cpp调用了b.cpp中某个函数,那么b.cpp肯定是要在a.cpp之前的[暂不考虑交叉调用]。

7.       应用程序运行时报错Fatal signal***

Fatal signal 11 (SIGSEGV) at 0x00000004 (code=1), thread 23487 (mple)

错误原因是因为访问了非法访问的内存地址,具体的原因可能是访问了null对象或者数组,很有可能是Java层传给Native层的对象是null,导致Native层访问了非法访问的地址

参考网址:

http://stackoverflow.com/questions/14495242/android-fatal-signal-11-sigsegv-at-0x00000040-code-1-error?rq=1

http://stackoverflow.com/questions/10787676/fatal-signal-11-sigsegv-at-0x00000000-code-1

8.       预览图片对图片进行保存得到的图片无法打开

关于Camera.PreviewCallback 调用的三种方式

参考网址:

http://blog.csdn.net/ocean20/article/details/8772196

错误的原因是Android中的BitmapFactory.decodeByteArray只支持一定的格式,camara支持的previewformat格式为NV21,所以在获得bitmap时,需要进行转换,通过YuvImage类来转换成JPEG格式,然后再保存到文件中

参考网址:

http://www.cnblogs.com/liuan/archive/2012/01/10/2318300.html

9.       图片路径传递给JNI层之前是正确的,但是被解析之后却发生了错误

使用自定义的将jstring转换成char*的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
staticchar* jstringToString(JNIEnv* env, jstring jstr) {
                                   
    char* rtn = NULL;
                                   
    jclass clsstring = env->FindClass("java/lang/String");
                                   
    jstring strencode = env->NewStringUTF("utf-8"); //"gbk");//
                                   
    jmethodID mid = env->GetMethodID(clsstring, "getBytes",
                                   
            "(Ljava/lang/String;)[B");
                                   
    jbyteArray barr = (jbyteArray) env->CallObjectMethod(jstr, mid, strencode);
                                   
    jsize alen = env->GetArrayLength(barr);
                                   
    jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
                                   
    if (alen > 0) {
                                   
        rtn = (char*) malloc(alen + 1);
                                   
        memcpy(rtn, ba, alen);
                                   
        rtn[alen] = '\0';
                                   
    }
                                   
    env->ReleaseByteArrayElements(barr, ba, 0);
                                   
    return rtn;
                                   
}

暂不确定 env->GetStringUTFChars 这个方法有没有问题

10.    使用ADB命令向AVD中复制文件或文件夹时报错

默认情况下avd对应的目录是只读的,去掉只读就好了

然后通过adb命令导入文件件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
samsung@samsung-PC ~
                                    
$ cd /cygdrive/g
                                    
samsung@samsung-PC /cygdrive/g
                                    
$ adb -e push Data /sdcard/Data
                                    
push: Data/t31.txt -> /sdcard/Data/t31.txt
                                    
push: Data/StructModel.bin -> /sdcard/Data/StructModel.bin
                                    
push: Data/sait_3D_model_1017.wfm -> /sdcard/Data/sait_3D_model_1017.wfm
                                    
push: Data/sait_3D_model_0819.wfm -> /sdcard/Data/sait_3D_model_0819.wfm
                                    
push: Data/sait_3D_model.wfm.bak -> /sdcard/Data/sait_3D_model.wfm.bak
                                    
push: Data/sait_3D_model.wfm -> /sdcard/Data/sait_3D_model.wfm
                                    
push: Data/model_M_mouth.bin -> /sdcard/Data/model_M_mouth.bin
                                    
push: Data/model_M_eye.bin -> /sdcard/Data/model_M_eye.bin
                                    
push: Data/model_M_10.bin -> /sdcard/Data/model_M_10.bin
                                    
push: Data/model_HR_10.bin -> /sdcard/Data/model_HR_10.bin
                                    
push: Data/model_HL_10.bin -> /sdcard/Data/model_HL_10.bin
                                    
push: Data/model_FR_10.bin -> /sdcard/Data/model_FR_10.bin
                                    
push: Data/model_FL_10.bin -> /sdcard/Data/model_FL_10.bin
                                    
push: Data/modelMap5.bin -> /sdcard/Data/modelMap5.bin
                                    
push: Data/modelMap4.bin -> /sdcard/Data/modelMap4.bin
                                    
push: Data/modelMap3.bin -> /sdcard/Data/modelMap3.bin
                                    
push: Data/modelMap2.bin -> /sdcard/Data/modelMap2.bin
                                    
push: Data/modelMap1.bin -> /sdcard/Data/modelMap1.bin
                                    
push: Data/Classifier_0627.txt -> /sdcard/Data/Classifier_0627.txt
                                    
19 files pushed. 0 files skipped.
                                    
205 KB/s (12493813 bytes in 59.350s)

参考网址:

http://www.crifan.com/ddms_import_file_error_transfer_error_read_only_file_system/

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
以上。

如何修改hosts(不定期更新)

 

通过hosts可以访问的自己去google一下原理大笑

修改流程

第①步

Windows 在C:\Windows\System32\drivers\etc下,把你下载到的host文件直接覆盖

OS X 在 Finder 窗口按下[前往][前往文件夹…],输入 /etc 回车,将 hosts 文件拖拽到桌面,双击修改保存,再将其拖拽回 /etc ,鉴定替换。

Linux 在终端运行命令 sudo vi /etc/hosts 修改。

Android、iOS 使用 iFile 或其它文件管理器应用修改 /etc/hosts,并照原样修改好权限和所有者。

第②步:刷新DNS缓存

Windows 按下 Windows+R 键,运行 cmd ,在命令提示符运行命令 ipconfig /flushdns

OS X 10.9OS X 10.10.4+ 在[应用程序][实用工具][终端]运行命令 sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder

OS X 10.10 在[应用程序][实用工具][终端]运行命令 sudo discoveryutil udnsflushcaches

OS X 10.9 在[应用程序][实用工具][终端]运行命令 dscacheutil -flushcache; sudo killall -HUP mDNSResponder

OS X 10.7 ~ 10.8 在[应用程序][实用工具][终端]运行命令 sudo killall -HUP mDNSResponder

Linux 在[终端]运行命令 /etc/rc.d/init.d/nscd restart

Android、iOS 重新启动设备

第③步:如果你有一天不能访问了,再回来看看,hosts可能已经更新了

2015-05-29:HOSTs地址:(点击我->)
2015-06-012:HOSTs地址:(点击我->)

2015-08-05 hosts地址:点击我

2015-08-17 host地址:(点击我啊,快点)

2015-09-06 host地址:(点击我啊,快点)

2015-12-06 host地址:(点击我下载