标签:native 编辑器 android jni lame
1、JNI简介
JNI全称为Java Native Interface(JAVA本地调用)。从Java1.1开始,JNI成为java平台的一部分,它允许Java代码和其他语言写的代码(如C&C++)进行交互。并非从Android发布才引入JNI的概念的。
2、JNI与NDK
简单来说,Android的NDK提供了一些交叉编译工具链和Android自带的库,这些Android的库可以让开发者在编写本地语言的程序时调用。而NDK提供的交叉编译工具链就对已经编写好的C&C++代码进行编译,生成库。
当然了,你也可以自己搭建交叉编译环境,而不用NDK的工具和库。然后生成库,只要规范操作,一样可以生成能让JAVA层成功调用的库文件的。
使用JNI技术,其实就是在Java程序中,调用C语言的函数库中提供的函数,来完成一些Java语言无法完成的任务。由于Java语言和C语言结构完全不相同,因此若想让它们二者交互,则需要制定一系列的规范。JNI就是这组规范,此时 Java只和JNI交互,而由JNI去和C语言交互。
JNI技术分为两部分:Java端和C语言端。且以Java端为主导。
|- 首先,Java程序员在Java端定义一些native方法,并将这些方法以C语言头文件的方式提供给C程序员。
|- 然后,C程序员使用C语言,来实现Java程序员提供的头文件中定义的函数。
|- 接着,C程序员将函数打包成一个库文件,并将库文件交给Java程序员。
在Java程序执行的时候,若在某个类中调用了native方法,则虚拟机会通过JNI来转调用库文件中的C语言代码。提示:C代码最终是在Linux进程中执行的,而不是在虚拟机中。
下面是一个Android调用JNI实现通过LAME转码器实现wav格式到MP3格式的转换.
准备:首先下载lame源码文件。
需要三个条件 :cgywin,cdt,ndk才能实现JNI的开发。
开发lame需要从http://lame.sourceforge.net/选择Using Lame 下载源代码。
新建工程
1、Android主界面布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<EditText
android:id="@+id/editText1"
android:hint="源wav文件的路径"
android:text="/sdcard/118/ccc.wav"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</EditText>
<EditText
android:id="@+id/editText2"
android:hint="目标MP3文件的路径"
android:layout_width="match_parent"
android:text="/sdcard/118/ccccc.mp3"
android:layout_height="wrap_content" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="转化"
android:onClick="convert"
/>
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="获取lame版本号"
android:onClick="getversion"
/>
</LinearLayout>
首先是建立JNI目录
1、把lameC语言源码导入jni中
2、创建Android.mk文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Hello
LOCAL_SRC_FILES := bitstream.c fft.c id3tag.c mpglib_interface.c presets.c quantize.c reservoir.c tables.c util.c VbrTag.c encoder.c gain_analysis.c lame.c newmdct.c psymodel.c quantize_pvt.c set_get.c takehiro.c vbrquantize.c version.c Hello.c
LOCAL_LDLIBS += -llog
include $(BUILD_SHARED_LIBRARY)
3、编写C语言文件
#include <stdio.h>
#include <jni.h>
#include "com_example_ndkpassdata_DataProvider.h"
#include <android/log.h>
#include<malloc.h>
#define LOG_TAG "System.out.c"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
char* Jstring2CStr(JNIEnv* env, jstring jstr) {
char* rtn = NULL;
jclass clsstring = (*env)->FindClass(env, "java/lang/String"); //String
jstring strencode = (*env)->NewStringUTF(env, "GB2312"); // 得到一个java字符串 "GB2312"
jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes",
"(Ljava/lang/String;)[B"); //[ String.getBytes("gb2312");
jbyteArray barr = (jbyteArray)(*env)->CallObjectMethod(env, jstr, mid,
strencode); // String .getByte("GB2312");
jsize alen = (*env)->GetArrayLength(env, barr); // byte数组的长度
jbyte* ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);
if (alen > 0) {
rtn = (char*) malloc(alen + 1); //"\0"
memcpy(rtn, ba, alen);
rtn[alen] = 0;
}
(*env)->ReleaseByteArrayElements(env, barr, ba, 0); //
return rtn;
}
JNIEXPORT jint JNICALL Java_com_example_ndkpassdata_DataProvider_add(
JNIEnv *env, jobject obj, jint x, jint y) {
LOGD("x=%d", x);
LOGD("y=%d", y);
return x + y;
}
JNIEXPORT jstring JNICALL Java_com_example_ndkpassdata_DataProvider_sayHelloInc(
JNIEnv *env, jobject obj, jstring jstr) {
char *cstr = Jstring2CStr(env, jstr);
LOGD("cstr=%s", cstr);
char arr[7] = { ‘ ‘, ‘h‘, ‘e‘, ‘l‘, ‘l‘, ‘o‘, ‘/0‘ };
strcat(cstr, arr);
LOGD("newcstr=%s", cstr);
return (*env)->NewStringUTF(env, cstr);
}
JNIEXPORT jintArray JNICALL Java_com_example_ndkpassdata_DataProvider_intMethod(
JNIEnv *env, jobject obj, jintArray arr) {
int len = (*env)->GetArrayLength(env, arr);
LOGD("SHUZU length-=%d", len);
jint *intarr = (*env)->GetIntArrayElements(env, arr, 1);
int i = 0;
for (; i < len; i++) {
LOGD("intarr[%d]=%d", i, intarr[i]);
*(intarr + i) += 10;
//intarr[i] += 10;
}
(*env)->ReleaseIntArrayElements(env, arr, intarr, len);
return arr;
}
JNIEXPORT jint JNICALL Java_com_example_ndkpassdata_DataProvider_sub(
JNIEnv *env, jclass clazz, jint x, jint y) {
LOGD("x=%d", x);
LOGD("Y=%d", y);
return x - y;
}
4、使用cgywin工具进行ndk-build编译
成功之后
5、编写Activity文件
package cn.itcast.lame;
import java.io.File;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class LameActivity extends Activity {
private EditText et_wav;
private EditText et_mp3;
private ProgressDialog pd;
public native void convertmp3(String wav,String mp3);
public native String getLameVersion();
public native void stop();
static{
System.loadLibrary("Hello");
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et_wav = (EditText) this.findViewById(R.id.editText1);
et_mp3 = (EditText) this.findViewById(R.id.editText2);
pd = new ProgressDialog(this);
}
public void convert(View view){
final String mp3name = et_mp3.getText().toString().trim();
final String wavname = et_wav.getText().toString().trim();
File file = new File(wavname);
int size = (int) file.length();
System.out.println("文件大小 "+ size);
if("".equals(mp3name)||"".equals(wavname)){
Toast.makeText(this, "路径不能为空", 1).show();
return;
}
//convertmp3(wavname,mp3name);
pd.setMessage("转换中....");
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMax(size); // 设置进度条的最大值
//pd.setCancelable(false);
pd.show();
new Thread(){
@Override
public void run() {
convertmp3(wavname,mp3name);
pd.dismiss();
}
}.start();
}
public void setConvertProgress(int progress){
pd.setProgress(progress);
}
public void getversion(View view){
String version = getLameVersion();
Toast.makeText(this, version, 0).show();
}
}
6、运行程序
版权声明:本文为博主原创文章,未经博主允许不得转载。
Android JNI Lame编解码实现wav到MP3的转换
标签:native 编辑器 android jni lame
原文地址:http://blog.csdn.net/kai46385076/article/details/47609495