首页 > 代码库 > 以神经网络使用为例的Matlab和Android混合编程

以神经网络使用为例的Matlab和Android混合编程

http://www.cnblogs.com/bellkosmos/p/5598439.html

由于需要在一个Android项目中使用神经网络,而经过测试发现几个Github上开源项目的训练效果就是不如Matlab的工具箱好,所以就想在Android上使用Matlab神经网络代码(可是。。。)
这个问题大概处理了两天,原本预计5个小时的。。。
过程遇到了诸多一手坑以及看到相关资料的对新手不友好,所以就把过程记录下来希望能给后来者一些帮助
这个教程从0开始讲如何在Android App中使用Matlab的神经网络代码
整个过程大概可以分成这么几步:
  1. 首先你要在Matlab中写一个完整的神经网络
    1. 获取样本
    2. 样本导入
    3. 神经网络建模
    4. 神经网络训练
    5. 神经网络测试(优化建模)
  2. 然后你要在Matlab中重写一个神经网络,第二个神经网络的特殊之处是
    1. 首先这个神经网络必须写成函数,具体有几个细节
    2. 把第一个神经网络的训练结果net网络保存成mat文件
    3. 把相关需要用的但无法直接写入代码的数据也保存成mat文件(比如数据归一化的参数)
    4. 然后在函数中把上面几个mat文件导入,基本上就是一个完整的神经网络模型了
    5. 再加上一个神经网络计算语句,并把结果返回,这个函数就完成了
  3. 然后把这个Matlab神经网络函数进行打包,打包的结果是一个jar包
  4. 然后把这个jar包连同另一个jar包一块导入Andorid工程,并添加为外部依赖
  5. 最后在Android工程中写一个专门调用这个jar包接口代码的函数,传入输入变量,返回计算结果
  6. ()
 
1.在Matlab中写一个完整的神经网络
1.1.获取样本就不说了
1.2.样本导入
如何导入数据呢,一般matlab中有通用的数据存储格式,那就是Mat格式,但是我并不知道怎么编写这个格式
在我发现有办法可以把txt中的数据导入进去之后我就选定它了,因为这种格式也非常方便我用android输出,也就是说它是一种比较通用的信息交换格式
具体的操作方法非常简单:
  1. 你在txt中按这种格式保存数据:每行用回车隔开,每列用空格隔开
  2. 然后你在matlab中load这个文件,就能得到一个数据的矩阵了
代码如下:
 
alldata = http://www.mamicode.com/load(‘alldata.txt‘);
alldata = http://www.mamicode.com/alldata(:,:);
 
1.3. 1.4. 1.5. 这几个过程照着代码修改还是比较简单的(虽然matlab很久没用让我当时读得有点困难。。。),稍微提这么几点:
  1. (把经典书目《MATLAB神经网络30个案例分析》的源码包放到工作路径再进行阅读修改)
  2. 输出数据需要进行一下矩阵转换
  3. 使用newff工具函数来构建神经网络,使用matlab内部的工具箱(其实就是库函数)来建模、训练和计算,不需要自己写逻辑代码
  4. 中间各种矩阵的变换感觉不是很习惯,可以参看一下工作空间里的变量状态,或者一步步打印一些变量的结果来看
 
clc;
clear;
 
%导入300组数据
alldata = http://www.mamicode.com/load(‘alldata.txt‘);
alldata = http://www.mamicode.com/alldata(:,:);
 
%输入输出数据
input = alldata(:,2:33);
outputtemp = alldata(:,1);
%输出数据需要处理一下
output = zeros(300,2);%预先分配内存
for i=1:300
    switch outputtemp(i)
        case 0
            output(i,:) = [1 0];%意思是如果数据结果是0,则输出层的状态是[1 0],或者用第一个输出节点表示
        case 1 %能直接识别带小数位的数据
            output(i,:) = [0 1];
    end
end
 
%从中随机抽取280组数据作为训练数据,20组数据作为预测数据
k = rand(1,300);
[m,n] = sort(k);
 
input_train = input(n(1:280),:)‘;
output_train = output(n(1:280),:)‘;
 
input_test = input(n(281:300),:)‘;
output_test = output(n(281:300),:)‘;
 
%输入输出数据进行归一化处理
[inputn,inputps] = mapminmax(input_train);
[outputn,outputps] = mapminmax(output_train);
 
%网络结构构建32-6-2
net=newff(inputn,outputn,6);
 
%网络参数配置(迭代次数,学习率,目标)
net.trainParam.epochs=100;
net.trainParam.lr=0.1;
net.trainParam.goal=0.0004;
 
%网络训练
net=train(net,inputn,outputn);
 
%BP网络预测
%预测数据归一化
inputn_test=mapminmax(‘apply‘,input_test,inputps);
 
%网络预测输出
an=sim(net,inputn_test);
 
%网络输出反归一化
BPoutput=mapminmax(‘reverse‘,an,outputps);
 
%结果分析
figure(1)
plot(BPoutput,‘:og‘)
hold on
plot(output_test,‘-*‘);
legend(‘预测输出‘,‘期望输出‘)
title(‘BP网络预测输出‘,‘fontsize‘,12)
ylabel(‘函数输出‘,‘fontsize‘,12)
xlabel(‘样本‘,‘fontsize‘,12)
%预测误差
error=BPoutput-output_test;
 
figure(2)
plot(error,‘-*‘)
title(‘BP网络预测误差‘,‘fontsize‘,12)
ylabel(‘误差‘,‘fontsize‘,12)
xlabel(‘样本‘,‘fontsize‘,12)
 
figure(3)
plot((output_test-BPoutput)./BPoutput,‘-*‘);
title(‘神经网络预测误差百分比‘)
 
errorsum = sum(abs(error))
 
最后输出的结果还可以,虽然正确率一般,因为样本太少 。但是还能接受,是可以解释的结果:
技术分享
 技术分享

 

 
2.在Matlab中重写这个神经网络,为导出jar包做准备
2.1.首先这个神经网络必须写成函数
在matlab写一个函数的过程是这样的
  1. 在工作空间中右键新建函数,重命名后打开,就是这样
    技术分享技术分享
  2. matlab中的函数在这里一起趁热讲了(自己复习一遍)
    1. 整个函数有一头一尾两句固定的声明,头是以function开始,然后是:返回值 = 函数名(函数参数),尾是end,虽然一开始看得不适应,但是习惯还是很好理解的,跟其他的语言差不多
      1. 返回值可以没有,那就是直接 函数名(函数参数)
      2. 返回值可以有多个,参数也可以有多个,他们的形式是这样:function [x,y,z]=sphere(theta,phi,rho)
      3. 注意Matlab中不会对函数类型进行声明,所以很多时候你在写函数的时候一开始就要对输入参数进行一个检查 
    2. 然后下面接着是官方注释,第一句是摘要,之后是详细说明,这些东西会在预览的时候显示
    3. 接下来就是函数体了,你可以做各种事情,逻辑语句、调用其他函数
    4. 最后在end之前你需要定义返回值,matlab在这块有点特殊,你不用显示地指定return哪个变量,因为你第一句声明里有返回值变量,所以只要你的函数内容中有这个变量,那么最后执行到end的时候就会自动返回这个变量这时候的状态
    5. -----调用函数------
    6. 调用函数的形式跟函数声明的第一句是一毛一样的:[输出参数表]=函数名(输入参数表)
    7. 调用函数时,输入和输出参数的顺序应与函数定义时的一致,数目一定不能多于函数定于中的,可能可以少于
    8. 为什么可以少于,因为在函数内部可以通过nargin()和nargout()获取函数被调用时用户指定的输入、输出参数个数。所以如果这个函数里边有针对不同的少于输入少于输出的情况进行if else的话,就可以自动适应
  3. 那么在这里,我的输出是一个int,输入是一个行矩阵,或者说一个数组,我的函数开头就这么写了:
    function output = annforecastthi(input_test)
 
2.2.然后为了不在这个函数里对神经网络进行训练(因为matlab的设定就是无法把训练函数编译成Jar包),需要把先前神经网络中训练好的net保存成mat文件再在这里直接导出
  1. 把先前神经网络中训练好的net保存成mat文件 非常简单。直接在运算结束后再工作空间中右键net变量,保存为mat文件就可以了
  2. 然后导入的时候稍微有点麻烦
    1. 其实load mat文件有两种方式,一种是命令行方式,一种是函数方式。两种方式功能上没什么区别,但是推荐在函数里用函数方式
    2. 以导入一个结构体(归一化参数)为例:
      1. 命令行方式 :load anninputps inputps;
      2. 函数方式:
        技术分享
    3. 而导入net数据的时候还要麻烦一些:
      1. 命令行方式:load annnet net;
      2. 函数方式:(后边还要加一句把结构体转型成网络格式)
        技术分享
  3. 这里需要导入三个mat文件,一个net和两个归一化参数(后边要用来反归一化)
 
关于为什么不能把神经网络的训练函数编译成jar包
MATLAB官方论坛中看到这样一个回答:
You will not be able to compile any function which trains the network (like ADAPT). Though the link does not explicitly list these funcions (like ADAPT), they fall under the ‘All other command line functionality‘.
However, you can deploy a M function code which uses a pre-trained network. I believe the SIM function will deploy fine.
The workflow I see is:
1. In MATLAB, train you network using test input/output
2. Save the network (mat file?)
3. Create a deployable function which then uses the pretrained network for new data. The network itself would not change/adapt/train in this function
4. Compile and deploy the above function
大意:MATLAB compile不支持对神经网络工具箱中涉及到训练的函数命令进行编译,只能编译那些用在已训练好的网络上的函数命令
所以解决方法就是在matlab下训练好网络,将net保存为mat文件,然后再写一个m文件,load进mat文件
 
2.3.最后返回计算结果,第二个神经网络模型也是神经网络计算函数就完成了
output=find(BPoutput(:,1)==max(BPoutput(:,1)));
整个函数是这样:
 
function output = annforecastthi(input_test)
%ANNFORECAST
%   输入长度为32的行矩阵,输出为1或2
 
A = load(‘annnet.mat‘);
B = fieldnames(A);
net = A.(B{1});
net = network(net);
 
C = load(‘anninputps.mat‘);
D = fieldnames(C);
inputps = C.(D{1});
 
E = load(‘annoutputps.mat‘);
F = fieldnames(E);
outputps = E.(F{1});
 
%BP网络预测
%预测数据归一化
inputn_test=mapminmax(‘apply‘,input_test‘,inputps);
 
%网络预测输出
an=sim(net,inputn_test);
 
%网络输出反归一化
BPoutput=mapminmax(‘reverse‘,an,outputps);
 
%结果分析
%根据网络输出找出数据属于哪类
output=find(BPoutput(:,1)==max(BPoutput(:,1)));
 
end
 
3.把这个Matlab神经网络函数打包成一个jar包导出
3.1.吐槽
3.2.安装java开发环境
  1. 安装java开发环境是很简单的事情,正常的步骤是这样
    1. 去甲骨文的官网下最新的jdk文件
      1. 选择windows64位的下载
      2. 不要选jre,区别是jre只能用来运行,不能用来编译,它也比jdk要小很多
      3. 这个网站下东西可能很慢,这个时候可以自行搜索一些网盘里提供的
    2. 点击这个jdk.exe文件进行安装,安装过程没什么好说的
    3. 安装完好像说现在的jdk不配置环境变量也没关系,但以前的要配置环境变量,那就配置吧,这个会单独在后边写
  2. 然后我其实是之前就有安装的,但是在后边生成Jar包的时候出现了问题
    1. 经过排查,发现是jdk的版本相对matlab版本太高了:目前我的这个matlab2015b对应的是jdk7,所以我现在jdk8都不可以。(参考:matlab 2014a 用jdk1.7;matlab 2013a 用jdk1.6)
    2. 于是就只能降低jdk版本了,如何降低呢,其实很简单,你的系统中是可以同时安装多个jdk版本的不会冲突,最后你希望编译的时候用哪个版本,就在环境变量里配置哪个版本,非常方便
      技术分享技术分享
    3. 但是下载的时候也会遇到个问题,因为官网找不到旧版本的下载,我就是搜索了一个然后安装,安装完修改了一下环境变量,最后ok了
 
3.3.配置环境变量
  1. 配置JAVA环境变量
    1. 具体的做法是:
      1. 我的电脑——属性——高级设置——高级——环境变量
      2. 在系统变量里添加一个键值对:JAVA_HOME(大小写不敏感),和jdk安装后的位置路径(为javac.exe所在目录D:\Program Files\Java\jdk1.6.0_13\bin的上一层)
      3. 技术分享技术分享
      4. 配置完之后这样可以验证
      5. 技术分享技术分享
    1. 另外说一点是,即使配置了这个java path,但Eclipse和AS中还有独立的配置:
      Eclipse:Window -> Preferences->Java -> Compiler 设置 "Compiler compliance level" 为 1.6 (相应版本)
      AS:点击File,选择Other Settings,选择Default Project ,Structure...
  2. 配置path
    1. 也是在系统变量里添加
    2. 变量名是path,值是【.;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;D:\Program Files\MATLAB\R2015b\bin】
    3. 现在我其实是这样的,居然也可以,不是很懂 【%Java_Home%\bin;%Java_Home%\jre\bin;C:\ProgramData\Oracle\Java\javapath;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Calibre2\;C:\Program Files\MATLAB\R2015b\runtime\win64;C:\Program Files\MATLAB\R2015b\bin;C:\Program Files\MATLAB\R2015b\polyspace\bin;C:\Program Files\MATLAB\MATLAB Runtime\v90\runtime\win64】
  3. 配置CLASSPATH
    1. 也是在系统变量里添加
    2. 变量名是path,值是【.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar;D:\Program Files\MATLAB\R2015b\toolbox\javabuilder\jar\javabuilder.jar;%JAVAHOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar】
    3. 现在我其实是这样的,居然也可以,不是很懂【.;%Java_Home%\bin;%Java_Home%\lib\dt.jar;%Java_Home%\lib\tools.jar】
 
3.4.打包的操作
在2015版本中操作跟前面版本的可能有很大的不同(跟2013都不一样,前面的也各自不一样orz),就只说在这个版本中的步骤
  1. 在命令行区域输入命令:deploytool,弹出对话框,然后你选择第三个library compiler
    技术分享技术分享
  2. 于是打开了一个大界面,在这个界面里要做五件事
    1. 1这选择java
    2. 2这点击添加你的这个m函数(2旁边这个框保持原样,不用打钩)
    3. 3这块一般都会改一你觉得适合的名字
    4. 关键4这一定要把你m函数中load的数据文件一块加进来
    5. 点击开始打包
  3. 技术分享技术分享
  4. 打包需要一点时间,结束后如果成功就会在工作空间路径下生成一个项目,项目中能找到输出Jar文件,这个就是我们的要的
    技术分享技术分享

     

4、把jar导入工程中
  1. 除了刚才生成的这个Jar包之外,还需要导入另一个Jar包,这个jar包就是MATLAB中带的jarbuild.jar 这个包,一般路径是E:\Program Files\MATLAB\R2013a\toolbox\javabuilder\jar   (MATLAB解析jar包文件)
  2. 用AS往Android工程导入JAR包的步骤是这样的
    1. 将jar文件复制、粘贴到app的libs目录(app—src—main—libs)中(此时虽然jar已经复制黏贴过来了,但是还未导入,所以看不到jar中包含的内容。而已导入的jar,则可以看到jar中内容)
    2. 右键点击jar文件,并点击弹出菜单中的“Add As Library”,将jar文件作为类库添加到项目中
    3. 删除jar包 的步骤
      1. 选中项目
      2. 点击 File——>Project structure——>module——>app
      3. 选择 “dependencies”,选择你要删除的jar包,点击减号
  3. 用Eclipse往JAVA工程导入JAR包的步骤是这样的
    1. 在java工程下新建一个lib文件夹(不新建也行,只是为了规范),直接把jar包拖入这个文件夹
    2. 右键,添加依赖
    3. 技术分享技术分享
 
5、写一个专门的工具方法作为调用Matlab函数的接口,传入输入变量,返回计算结果
怎么写:
  1. 导入结束后,你能看到其实是这样的
  2. 所以你写接口的话非常简单
    1. 先new一个这个类,然后调用类的这个方法,输入输出
    2. 直接结束
然后写的话需要注意这么几点:
  1. (参数和返回值的数据类型什么的,matlab 的帮助文档matlab builer for JA中说得很详细)
  2. 必须catch一下MWException,这个是matlab里边的
  3. 输入:
    1. 你的matlab函数是这样写的:output = annforecastthi(input_test)
    2. 你的函数里是把输入当成一个大小为32的行矩阵来用的,所以正常想在这应该是输入一个数组
    3. 但是根据代码提示,你会发现不完全是这样,而是:第一个参数是输出数据个数,之后是一个个的输入数据,输入数据可以直接是一个数组
  4. 输出:
    1. 同样,我在matlab函数里写的输入是一个int值,为1或者2
    2. 但是在这里,你的输出是一个Object[ ],如果输出只有一个的话,那就是result[0]
    3. 另外如果result[0]返回的是一个数组,可以通过如下的方法解析(供参考)
      1. MWNumericArray a = new MWNumericArray(Double.valueOf(result[0].toString()),MWClassID.DOUBLE);
      2. MWNumericArray temp = (MWNumericArray)result[0];
      3. float [][] weights=(float[][])temp.toFloatArray();
 
public class TestMatlab {
       public static void main(String[] args){
              try {
                     ANNMatlab annMatlab = new ANNMatlab();
                      double[] array = {74.5,75.5 ,83.3 ,93.4 ,93.9 ,90.1 ,86.1 ,... };
                     Object result[]=annMatlab.annforecastthi( 1,array);
                     //函数第一个参数是输出数据个数,之后的就是是输入数据。
                                     System.out.println("result=="+result[ 0]);
              } catch (MWException e) {
                     e.printStackTrace();
              }
       }
}
 
然后在JAVA项目中运行,获得了正确的输入
技术分享
技术分享
但是当把这个项目放在Android项目中运行的时候,发现崩溃并且报错了
 
 
6、Android项目中无法直接使用Matlab中导出的jar包
根据前文的正确操作到这一步的时候,你会发现Android项目还是崩溃了,并且报这样的错
【java.lang.UnsatisfiedLinkError: Failed to find the required library libmwmclmcrrt.so.9.0 on java.library.path. 】
这个错误的意思是:在java路径上缺少这个so文件
这个java路径可以通过【System.out.println(System. getProperty("java.library.path")); 】这句代码打印,我这里打印结果是zycn根文件夹,也就是整个项目的根文件夹
而这个libmwmclmcrrt.so.9.0又是什么呢
  1. so文件和dll文件都是动态链接库(说白了就是一些库函数),dll文件是windows系统中使用的,而so文件是Linux系统中使用的
  2. 而这个libmwmclmcrrt.so.9.0大概是matlab代码需要的,但是为什么需要呢?不应该搞定之后都会有吗?
    1. 搜索引擎上一些缺少.so文件的问题发生在Linux系统下,然后他们的解决办法都是一个,重新配置环境变量,因为好像在linux上配置这个环境变量很容易出问题(https://www.baidu.com/s?ie=UTF-8&wd=libmwmclmcrrt.so.9.0)(http://blog.csdn.net/chujiangke001/article/details/17427659)(http://www.linuxidc.com/Linux/2013-03/80301.htm)(http://www.aiuxian.com/article/p-2193879.html)(http://blog.csdn.net/xcmax/article/details/27523419)(http://www.aiuxian.com/article/p-2193879.html)
    2. 搜索引擎上还有缺少dll文件的,一部分是环境变量的配置问题,一部分是需要手动安装某个800多M的文件(如果你要在没有安装matlab的机器上用java调用这些jar包,怎么办?也是可以的,不过,不过你要先在机器上安装matlab提供的MATLAB Compiler Runtime (MCR) ,它的安装文件在D:\program files\study\MATLAB\R2007b\toolbox\compiler\deploy\win32下(你的安装目录下)文件名MCRInstaller.exe)(http://www.cnblogs.com/ellisonDon/archive/2012/10/30/2746457.html)(http://jingyan.baidu.com/article/ab0b5630b801ddc15afa7df1.html)
    3. 但这里因为在java项目中能成功运行,在android中不行,所以自然会想到是android系统的环境变量配置问题或者说就是跟android系统有关
后来在matlab官方论坛和stackoverflow上更换了下关键词【直接matlab+android】,有找到对于这个问题的直接解释,还有曲线救国的办法。相关的问题还很多,看来是很多人都遇到了这个问题
 
http://cn.mathworks.com/matlabcentral/answers/280039-deployed-jar-file-to-create-android-app?s_tid=srchtitle
The .jar files that Compiler SDK generates cannot be run on Android. The .jar has a small interface to call upon the machine code library that is MCR, and otherwise the .jar contains encrypted data files. The encrypted data files are the "compiled" .m code, which is not compiled to java, but rather to MATLAB‘s internal threaded interpreter. MCR decrypts the encrypted pcode‘d .m files and uses them as data to be processed by the threaded interpreter. The encrypted data files themselves can be fairly operating system independent, but you need MCR to interpret them, and MCR is in x86 or x64 machine code for all versions of MATLAB since about R2009a. Android does not run on x86 or x64: Android runs on ARM processors (or possibly PowerPC as well, I am not certain.)
In short, you cannot use Compiler SDK to generate for anything useful on Android.
At this time, the only way to deploy for Android is to use Simulink with Target set to Android. You can have your Simulink blocks call a MATLAB Function block which is specialized MATLAB code (that has to be careful about how it allocates memory.) There is not much graphics you can do with this mechanism but it is the best that is available at this time.
I happened to look last night at some of the blocks available for deployment to a couple of the Android Galaxy devices. There is a block which accepts R, G, and B signals and displays the result as the screen. It would require computing the entire screen, I suspect. Some of the routines in the Vision toolbox help in that.
大意:matlab生成的jar包不能直接在android上运行,还需要用一个叫MCR的东西进行解码(The MATLAB Compiler Runtime (MCR) has the same System requirements as MATLAB. See System Requirements - Android is not one of them.它是matlab代码解析器),而MCR目前只能运行在X86或者X64的CPU上,但因为android是运行在ARM CPU上,所以是不可能使用的。
然后它说:此时,部署Android的唯一方法是使用Simulink与目标设定为Android。你可以有你的Simulink模块调用MATLAB函数的MATLAB代码块是专业(需注意如何分配内存)没有多大的图形可以做这种机制,但它是最好的,此时可用。
后边这个就看不懂了:我碰巧看的最后一个晚上的一些块可供部署到一对夫妇的安卓银河设备。有一个块,它接受R,G和B信号,并显示屏幕的结果。它将需要计算整个屏幕,我怀疑。一些例程中的“视觉工具箱”中的帮助。
 
http://cn.mathworks.com/matlabcentral/answers/274977-matlab-convert-to-android?s_tid=srchtitle
I have not read about what can be done in R2016a. The situation as of R2015b was that in order to generate code for Android from MATLAB, what you needed to do was include the MATLAB code in a MATLAB Function block in Simulink and tell Simulink to target Android; there was no direct path for MATLAB to Android.
大意:你需要做的是包括在Simulink MATLAB功能块的matlab代码告诉Simulink目标Android
 
http://cn.mathworks.com/matlabcentral/answers/58587-can-i-install-matlab-runtime-mcr-on-android-tab?s_tid=srchtitle
However, you should be able to use the MATLAB Coder product to generate a standalone C/C++ library from your MATLAB code and then invoke that from your Android application, possibly using JNI.
大意:你可以使用一个叫MATLAB Coder的工具来生成可以独立运行的C/C++库,他们可以在android中通过JNI来直接运行
 
http://cn.mathworks.com/matlabcentral/answers/277038-utilizing-matlab-code-in-android-application?s_tid=srchtitle
MATLAB code that is put into a Simulink MATLAB Function Block (with appropriate adjustments made) can be generated for Android target using Simulink. There are a bunch of restrictions on this, but I think it can access the Android Sensor information for supported devices (Galaxy S4, Galaxy Note 2)
大意:matlab代码,把MATLAB的一个Simulink功能块(适当调整)可以为Android使用Simulink生成目标。有一些限制,但我认为它可以访问支持的设备Android传感器信息(Galaxy S4,Galaxy Note 2)
 
http://cn.mathworks.com/matlabcentral/answers/271412-is-it-possible-to-program-app-of-android-with-matlab?s_tid=srchtitle
From MATLAB, you can communicate with Android camera and with Android sensors (at least for some models), but it is not possible to generate code for Android. You need to use Simulink to generate code for Android.
MATLAB Coder does not know about Android, so MATLAB Coder cannot generate Android calls for user interaction, networking, graphics, and so on. MATLAB Coder can generally generate C or C++, but unless it has been given information about the target system, MATLAB Coder has a library of calls that is not even as complete as the Standard C Library. This is not enough to create an Android "app"; at most it is enough to create a utility program.
Simulink does know how to target Android, so if you have a Simulink model and use the Android-specific blocks, Simulink can create apps. See http://www.mathworks.com/hardware-support/android-programming-simulink.html
大意:可以用Simulink
 
http://cn.mathworks.com/matlabcentral/answers/264272-how-could-i-integate-matlab-library-into-android?s_tid=srchtitle
.so files are Linux Shared Object libraries. Those .so files are only available for Intel x86 (32 bit) and x64 (64 bit) instruction set (including AMD CPUs that implement those.) They are not available for ARM or other instruction architectures.
大意:.so文件本身也只能再X86的系统上使用,而不能在ARM上使用(这个存疑)
 
http://stackoverflow.com/questions/9662730/how-to-integrate-matlab-code-library-with-android
http://stackoverflow.com/questions/30865800/import-java-package-from-matlab-deploytool-to-android-studio-app?rq=1
The .jar file requires the MATLAB Compiler Runtime (a freely redistributable component that you get with MATLAB Compiler and MATLAB Builder products) to be present. The MCR has a much larger footprint than is suitable for the typical Android device (it‘s like a copy of MATLAB itself, without the user interface).
You could think about either
1)Running your MATLAB .jar file remotely on a server, and having your Android application connect to it, or
2)Instead of using MATLAB Compiler and Builder products, use MATLAB Coder, which will convert a subset of the MATLAB language directly into C code. This C code doesn‘t require the MCR, and could be compiled to run directly on Android. Make sure your MATLAB algorithm falls within, or can be expressed in, the appropriate subset of the MATLAB language.
大意:前面都一样不说了,后边提了两个解决办法:1)不要再app上用Matlab代码,转移到服务器上;2)用MATLAB Coder编译成可以不需要MCR支持才能运行的C/C++文件
 
http://stackoverflow.com/questions/9662730/how-to-integrate-matlab-code-library-with-android
A new feature in Matlab 2014a:
http://www.mathworks.com/help/simulink/samsung-galaxy-android-devices.html
You can now directly install (limited set of) models to Samsung Android devices, and this should work actually on any Android device.
大意:2014的新版本中,你可以直接把matlab模型安装在三星安卓设备上,实际上就可以安装在所有安卓设备上
 
总结一下上面的内容:
  1. 直接在android app上使用deploytool生成的jar包是不行的,因为它不能独立运行,还需要MCR的支持,而由于CPU的原因MCR是不能运行在android环境的
  2. 那么其他可行的间接办法有这些
    1. 不要在app上用Matlab代码,转移到服务器上
    2. MATLAB Coder编译成可以不需要MCR支持才能运行的C/C++文件,然后使用JNI的方法在android app上使用
    3. 可以通过一种【include the MATLAB code in a MATLAB Function block in Simulink and tell Simulink to target Android】的方法来做
 
对于第一个间接办法,肯定是可行的,但由于目前我这条件的限制,是无法实现了
对于第二个间接办法,肯定也是可行的,不过稍显复杂,目前我对此也没有涉猎
对于第三个间接办法,我去简单了解了一下,但是搞下来毫无头绪:
  1. 首先我没有找到step by step的教程,所以只能一个个自己去搜索
  2. 于是先去看了matlab的simulate系统,两个感受:
    1. 功能非常丰富繁杂
    2. 找不到所谓的跟搞一个android虚拟机有关的东西
    3. 这个中文入门教程还可以:http://wenku.baidu.com/link?url=40Z4TdIwCDm35TsAmk8NgVwL1UtJzYoVhe8dwKs87kytiIUx25kIgU18zJcV65UTH7kgHyh0Cfq-pGgDjdrXeSE5j3f_B1vmwG284hTiyQG
  3. 然后我看了下这个什么三星虚拟机,发现:这个东西好像只是跟什么传感器有关,可以在matlab中获取三星手机传感器的数据,跟我现在的需求没有关系
    1. http://cn.mathworks.com/examples/simulink/mw/android_product-androidusageexample-working-with-samsung-galaxy-android-devices-block-library?s_tid=srchtitle
    2. https://www.baidu.com/s?wd=matlab%20android&pn=30&oq=matlab%20android&ie=utf-8&rsv_pq=c9a5520000070f35&rsv_t=9669WDl4Z8FRLpkV6StuMtaAWluCKlVLBmZBF1KUbEB63kqnQiyTeEhD7jo&rsv_page=1
  4. 最后时间关系没有继续探索下去
 
7、另一个解决办法
其实推荐使用上面的第一个或第二个间接办法,都很不错
不过最后我采用了个间接但是比较简单可能效果不好的方法:直接找了一个java写的神经网络开源项目,读了一下了解怎么用,就直接放进app中使用了
所以这个教程其实还差一步没有结束,之后有空把JNI学一下再来更新这个部分
 
参考资料:已在文中列出

以神经网络使用为例的Matlab和Android混合编程