Android JNI 使用别人的.so类库(盗版美图秀秀)

项目简介:

该项目为盗版的美图秀秀

详细介绍:

在开发中,可能使用别人写的C方法,这里就用美图秀秀为例子,演示如何使用别人已经编译好的.so类库。
整个应用如下:
Android JNI 使用别人的.so类库(盗版美图秀秀)_第1张图片
用户点击按钮后,会将一张图片加入美图效果(如色彩变暗,复古或者其他效果):
Android JNI 使用别人的.so类库(盗版美图秀秀)_第2张图片
可以看到,图片的效果的确变了,整个图片变得黄了一些

该应用涉及到的知识有:

  • 1.使用已有软件的.so类库
    首先要先把别人的APK反编译,得到本地方法(一般在JNI.java文件中),然后解压缩APk文件,得到.so类库,最后就是如何在java中调用C框架的事了

注意:

  • 1.本题中美图秀秀的APK文件反编译后,只得到了支持arm架构的CPU的.so类库,所以只能在arm架构CPU的手机上运行该项目

步骤:

1.创建一个Android项目

准备工作。由于用到美图秀秀的.so类库,所以把美图秀秀解压,然后找到打开\lib\armeabi,发现该文件夹下有个libmtimage-jni.so文件,直接把该文件连同armeabi文件夹复制,然后粘贴到项目的libs文件夹下。

Android JNI 使用别人的.so类库(盗版美图秀秀)_第3张图片

将美图秀秀的安装包mtxx.apk反编译(详情请看这篇文章APK文件反编译工具),反编译后打开得到的jar包,如下所示:

Android JNI 使用别人的.so类库(盗版美图秀秀)_第4张图片

看到有个JNI文件,打开后把代码全部复制,然后在自己的项目下创建一个同名文件,粘贴代码。要求自己项目下的同名文件包名都要一样,如下所示:

Android JNI 使用别人的.so类库(盗版美图秀秀)_第5张图片

2.布局文件

编写activity_mian.xml文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="hhh.exercise.ujni_d.MainActivity" >

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="click"
        android:text="美化一下"
        android:textColor="#0000ff"
        android:textSize="30sp" />

    <ImageView
        android:id="@+id/iv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

LinearLayout>

布局文件很简单,就一个Button和一个ImageView。ImageView用来显示一张图片,当点击Button后该图片效果会发生改变。

3.Activity

编写MainActivity.java 文件:

import com.mt.mtxx.image.JNI;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;

public class MainActivity extends Activity {

    private ImageView iv;
    private Bitmap bitmap;

    static {

        // 加载类库。但是项目中使用的是别人的类库,没有jni文件,更没有Android.mk文件,无法知道类库名称
        // 根据掐头去尾的原则,导入的类库/libs/armeabi/libmtimage-jni.so,把libmtimage-jni.so的lib和.so去掉就行
        System.loadLibrary("mtimage-jni");

    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        iv = (ImageView) findViewById(R.id.iv);

        bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.t2);
        iv.setImageBitmap(bitmap);

    }

    public void click(View view) {

        JNI jni = new JNI();

        // 类库是从美图秀秀中盗取的,所以没有注释,只能靠自己猜测类JNI中的方法作用
        // 这里我们以其中一个方法为例子

        int width = bitmap.getWidth();
        int height = bitmap.getHeight();

        // 创建数组,用于保存图片中又有的像素信息
        int[] pixels = new int[width * height];

        // 获取所有的像素信息,保存到pixels数组中
        bitmap.getPixels(pixels, 0, width, 0, 0, width, height);

        // 第一个参数是像素信息
        // 第二个参数是图片的宽
        // 第三个参数是图片的高
        // 该方法会改变pixels的信息
        jni.StyleLomoB(pixels, width, height);

        // 用改变后的pixels构建一个Bitmap对象
        Bitmap bitmap2 = Bitmap.createBitmap(pixels, width, height, bitmap.getConfig());

        // 把新图显示在界面上
        iv.setImageBitmap(bitmap2);

    }

}

整个Demo完成了。但是有一点,就是不知道JNI类中的函数是干什么的,这个只能自己一个一个去用,然后看看效果是什么样的,就可以了。

你可能感兴趣的:(Android)