首先呢,我先做一下广告吧,我们团队是:IMUDGES(内蒙古大学精英开发者联盟 )大家有什么好的想法可以和我们交流,给我的博客留言!
在我几天不断的努力下,记事本的后台操作基本搞定了,现在和大家就一起分享一下,首先,记事本应该有增、删、该的功能吧,今天我就和大家一起看看这些功能怎么实现,当然这是我的个人思路,如果大家有更好的想法可以给我留言,一起讨论讨论;
1、首先,新建一个;
好,第一个记事写好了,然后就开始保存了。我是这样做的,保存的时候把我笔记的题目放在一个<li></li>标签里面,然后把写好这个日记的日期也取下来,我看了一下我手机上的记事本,就有这个功能,所以我也加上了这个功能。先看看效果。
这样就有了以上的界面,那么里面的代码怎么写的呢,我先给大家说一说这个日期是怎么弄的。看代码:
var today = new Date(); var year = today.getFullYear(); var month = (today.getMonth() + 1) < 10 ? '0' + (today.getMonth() + 1) : (today.getMonth() + 1); var day = (today.getDate()) < 10 ? '0' + (today.getDate()) : (today.getDate()); var hours = (today.getHours()) < 10 ? '0' + (today.getHours()) : (today.getHours()); var minutes = (today.getMinutes()) < 10 ? '0' + (today.getMinutes()) : (today.getMinutes()); var seconds = (today.getSeconds()) < 10 ? '0' + (today.getSeconds()) : (today.getSeconds()); date1 = year + "-" + month + "-" + today.getDate() + " " + hours + ':' + minutes + ':' + seconds;
这样date1这样一个变量就是一个时间的字符串,把这个字符串的值穿到<li></li>这个标签里面,用jQuery做这些任务。
2、然后大家可以点击那个<li></li>标签,就是那个“我的第一个日记”,然后就是进入了你的写的内容了。看效果:
这里的内容我都设置成了只读的模式,目前大家是不能改动这个记事内容的,其实上一节的html5的代码中就有设置的,大家可以返回去看看那个代码。
3、大家可以重新编辑这个记事或删除这个记事,按选项会弹出一个对话框可以进行选择删除还是编辑。看效果:
如果大家选择编辑的话,上面写的内容就变成可写的了,大家就可以改动了。
大家应该能看出来吧,我的标题也变化了,上面显示的时间是你做完修改的时间!再然后看看删除:
这样就删除功能也有了。好吧,效果都看完了,说说代码吧。
var today = new Date(); var year = today.getFullYear(); var month = (today.getMonth() + 1) < 10 ? '0' + (today.getMonth() + 1) : (today.getMonth() + 1); var day = (today.getDate()) < 10 ? '0' + (today.getDate()) : (today.getDate()); var hours = (today.getHours()) < 10 ? '0' + (today.getHours()) : (today.getHours()); var minutes = (today.getMinutes()) < 10 ? '0' + (today.getMinutes()) : (today.getMinutes()); var seconds = (today.getSeconds()) < 10 ? '0' + (today.getSeconds()) : (today.getSeconds()); date1 = year + "-" + month + "-" + today.getDate() + " " + hours + ':' + minutes + ':' + seconds; var moban = $("#time"); $(function(){ var title; var content; $("#save").click(function(){ title=$("#texttheme").val(); content = $("#textcontent").val(); if(title=="") alert("theme is not null!"); else{ $.mobile.changePage("#page1","slideup"); $("#time").append(date1); $("#neirong").append(title); $("#time").slideDown("fast"); $("#content").slideDown("fast"); document.getElementById("texttheme").value=""; document.getElementById("textcontent").value=""; }}); $("#neirong").click(function(){ document.getElementById("opentexttheme").value=title; document.getElementById("opentextcontent").value=content; }); $("#bianji").click(function(){ $.mobile.changePage("#page2","slidedown"); document.getElementById("texttheme").value=title; document.getElementById("textcontent").value=content; $("#save").click(function(){ var today = new Date(); var year = today.getFullYear(); var month = (today.getMonth() + 1) < 10 ? '0' + (today.getMonth() + 1) : (today.getMonth() + 1); var day = (today.getDate()) < 10 ? '0' + (today.getDate()) : (today.getDate()); var hours = (today.getHours()) < 10 ? '0' + (today.getHours()) : (today.getHours()); var minutes = (today.getMinutes()) < 10 ? '0' + (today.getMinutes()) : (today.getMinutes()); var seconds = (today.getSeconds()) < 10 ? '0' + (today.getSeconds()) : (today.getSeconds()); date1 = year + "-" + month + "-" + today.getDate() + " " + hours + ':' + minutes + ':' + seconds; $("#time").empty(); $("#neirong").empty(); $("#time").append(date1); $("#neirong").append(title); }); }); $("#shanchu").click(function(){ $.mobile.changePage("#page1","slidedown"); $("#time").css("display","none"); $("#content").css("display","none"); title=""; content=""; }); });
说实话,我这人比较懒啊,就这样把整个的js文件的代码都靠过来了,本人习惯不是太好,反正能看懂的就多提意见,看不懂的给我留言。有了这个还有css里面的东西,写的不是很多,就是把一开始的显示的时间和题目的那个标签先影藏了,然后要用到的时候就把它给弄出来!看css代码吧:
#time{ display: none; } #content{ display: none; }就这么三四行,就是先把不该显示的东西先给影藏了!不过这就是一个练习吧,做的虽然不是很强大,但是有什么不足的地方还希望大牛指出,代码我就不一行一行解释了,不是很难,就是jQuery中的一些api。不懂的可以查一查jQuery的api。是在不懂的就直接把代码拷过去就行了。需要提醒的是,最好在google的chrome中运行,这个浏览器支持html5支持的比较好!好吧,没了,有什么小的作品再和大家分享!
在jquerymobile中我们如果使用网格去布局页面,jqm中提供了比较简单的网格布局。只要使用简单的CSS类就可以了。下面看一个例子代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>Grid Test</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="http://code.jquery.com/mobile/latest/jquery.mobile.min.css" /> <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script> <script src="http://code.jquery.com/mobile/latest/jquery.mobile.min.js"></script> </head> <body> <div data-role="page" id="first"> <div data-role="header"> <h1>Grid Test</h1> </div> <div data-role="content"> <div > <div > <p> 测试 </p> </div> <div > <p> 巩固完善基本药物制度和基层运行新机制是“十二五”期间深化医药卫生体制改革的重点,是实现2020年人人享有基本医疗卫生服务目标的重要基础。医改实施三年多来,基层医疗卫生机构综合改革全面推进,初步建立了基本药物制度,构建了维护公益性、调动积极性、保障可持续的基层运行新机制。为进一步深化改革,扩大医改成果,现就巩固完善基本药物制度和基层运行新机制提出如下意见。 </p> </div> </div> </div> </div> </body> </html>
代码中被<div >包围的将会分成两列,但是必须配合<div >才会起作用。这里ui-grid-a代表分为两列、ui-grid-b代表分为三列,以此类推。ui-block-a、ui-block-b、ui-block-c等分别代表第一列、第二列、第三列,以此类推。
代码效果如下:
现将native函数贴出来。
#include <jni.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <android/log.h> #include <dirent.h> #include <sys/stat.h> #include <unistd.h> #include <sys/statfs.h> #include <sys/types.h> #include <com_coder80_scaner_MainActivity.h> //#include <fcntl.h> #define LOG_TAG "SCANER" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) #define ARRAY_LENGTH 1024 static int i = 0; static JavaVM *gvm; static jobject giface; static const char *classPathName = "com/coder80/scaner/MainActivity"; static JNINativeMethod methods[] = { { "scanDir", "(Ljava/lang/String;)V", (void *)Java_com_coder80_scaner_MainActivity_scanDir}, { "getPathArray", "(Ljava/lang/String;)[Ljava/lang/String;", (void *)Java_com_coder80_scaner_MainActivity_getPathArray}, { "getTracksArray", "(Ljava/lang/String;)[Lcom/coder80/scaner/Track_Info;", (void *)Java_com_coder80_scaner_MainActivity_getTracksArray} }; jint JNI_OnLoad(JavaVM* vm, void* reserved) { jclass clazz = NULL; JNIEnv* env = NULL; jmethodID constr = NULL; jobject obj = NULL; LOGE("JNI_OnLoad"); gvm = vm; if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_4) != JNI_OK) { LOGE("GetEnv FAILED"); return -1; } clazz = (*env)->FindClass(env,classPathName); if (!clazz) { LOGE("Registration unable to find class '%s'", classPathName); return -1; } constr = (*env)->GetMethodID(env, clazz, "<init>", "()V"); if (!constr) { LOGE("Failed to get constructor"); return -1; } obj = (*env)->NewObject(env, clazz, constr); if (!obj) { LOGE("Failed to create an interface object"); return -1; } giface = (*env)->NewGlobalRef(env, obj); if ((*env)->RegisterNatives(env, clazz, methods, sizeof(methods) / sizeof(methods[0])) < 0) { LOGE("Registration failed for '%s'", classPathName); return -1; } return JNI_VERSION_1_4; } jobjectArray Java_com_coder80_scaner_MainActivity_getPathArray(JNIEnv *env, jobject obj, jstring jdirPath) { const char *dirPath = (*env)->GetStringUTFChars(env, jdirPath, NULL); jclass objClass = (*env)->FindClass(env, "java/lang/String"); jobjectArray textsArray = (*env)->NewObjectArray(env,(jsize)ARRAY_LENGTH,objClass,0); i = 0; scan_dir2(env,dirPath,textsArray); return textsArray; } void scan_dir2(JNIEnv *env,const char *directory,jobjectArray array) { DIR *dp; struct dirent *entry; struct stat statbuf; if((dp = opendir(directory)) == NULL) { perror("opendir"); return; } chdir(directory); jstring jstr; while ((entry = readdir(dp)) != NULL) { stat(entry->d_name, &statbuf); if (S_ISDIR(statbuf.st_mode)) { if ((strcmp(entry->d_name, ".") != 0) && (strcmp(entry->d_name, "..") != 0) && (entry->d_name[0] != '.')) { scan_dir2(env,entry->d_name,array); } } else { int size = strlen(entry->d_name); if (entry->d_name[0] != '.' //隐藏文件 && (statbuf.st_size/1024) > 300 //大于300k,表示肯能有mp3文件(忽略 <300k的mp3) && strcmp( ( entry->d_name + (size - 4) ) , ".mp3") == 0) { char* parentPath = (char*)malloc(1024); char* absolutePath = (char*)malloc(1024); //首先获取工作路径 getcwd(parentPath,1024); //LOGE("parentPath = %s \n", parentPath); strcpy(absolutePath,parentPath); char *p = "/"; absolutePath = strcat(absolutePath,p); absolutePath = strcat(absolutePath,entry->d_name); //statbuf.st_size, // LOGE("scan_dir(),file absolutePath = %s \n", absolutePath); jstr = (*env)->NewStringUTF(env,absolutePath); (*env)->SetObjectArrayElement(env,array,i,jstr);//必须放入jstring i++; // (*env)->ReleaseStringUTFChars(env,js, s); // LOGE("scan_dir2(),i = %d,file absolutePath = %s \n\n",i, absolutePath); free(parentPath); parentPath = NULL; free(absolutePath); absolutePath = NULL; } } } chdir(".."); closedir(dp); } void Java_com_coder80_scaner_MainActivity_scanDir(JNIEnv *env, jobject obj, jstring jdirPath) { const char *path = (*env)->GetStringUTFChars(env,jdirPath,NULL); LOGE("begin to call scan_dir() in the JNI,and path = %s \n",path); scan_dir(path); } void scan_dir(const char *directory) { DIR *dp; struct dirent *entry; struct stat statbuf; if((dp = opendir(directory)) == NULL) { perror("opendir"); return; } chdir(directory); //LOGE("pyb chdir directory = %s\n",directory); while ((entry = readdir(dp)) != NULL) { stat(entry->d_name, &statbuf); if (S_ISDIR(statbuf.st_mode)) { //printf("name = %s, size = %d\n", entry->d_name, (int)statbuf.st_size); if ((strcmp(entry->d_name, ".") != 0) && (strcmp(entry->d_name, "..") != 0) && (entry->d_name[0] != '.')) { scan_dir(entry->d_name); } } else { int size = strlen(entry->d_name); if (entry->d_name[0] != '.' && (statbuf.st_size/1024) > 300 //大于300k,表示肯能有mp3文件(忽略 <300k的mp3) && strcmp(entry->d_name + (size - 4), ".mp3") == 0){ //LOGE("scan_dir(),file st_size = %d \n\n",(statbuf.st_size/1024)); char* parentPath = (char*)malloc(1024); char* absolutePath = (char*)malloc(1024); //首先获取工作路径 getcwd(parentPath,1024); //LOGE("parentPath = %s \n", parentPath); strcpy(absolutePath,parentPath); char *p = "/"; absolutePath = strcat(absolutePath,p); absolutePath = strcat(absolutePath,entry->d_name); //statbuf.st_size, LOGE("scan_dir(),file absolutePath = %s \n", absolutePath); free(parentPath); parentPath = NULL; free(absolutePath); absolutePath = NULL; } } } chdir(".."); closedir(dp); } ////displayName //jfieldID disName; ////size //jfieldID trackSize; ////ext //jfieldID extName; ////filePath //jfieldID path; ////parentPath //jfieldID parent; // //jobject obj_main; JNIEXPORT jobjectArray JNICALL Java_com_coder80_scaner_MainActivity_getTracksArray(JNIEnv *env, jobject obj, jstring jdirPath){ const char *dirPath = (*env)->GetStringUTFChars(env,jdirPath,NULL); jclass objectClass = (*env)->FindClass(env, "com/coder80/scaner/Track_Info"); jobjectArray jobj_arr= (*env)->NewObjectArray(env,(jsize)ARRAY_LENGTH,objectClass, 0); obj_main = obj; LOGE("in JNI getTracksArray(),dirPath = %s \n", dirPath); //获取Java对象 /* * 或者 同样可以获取Java对象 * jclass objectClass = env->GetObjectClass(jobject); * */ //displayName // disName = (*env)->GetFieldID(env,objectClass,"displayName","Ljava/lang/String;"); //// //size //// trackSize = (*env)->GetFieldID(env,objectClass,"size"," L"); // //ext // extName = (*env)->GetFieldID(env,objectClass,"ext","Ljava/lang/String;"); // //filePath // path = (*env)->GetFieldID(env,objectClass,"filePath","Ljava/lang/String;"); // //parentPath // parent = (*env)->GetFieldID(env,objectClass,"parentPath","Ljava/lang/String;"); i = 0; scan_dir3(env,dirPath,jobj_arr); return jobj_arr; } jmethodID JavaMid = NULL; JNIEnv * jniEnvPlaying = NULL; /* * para obj: Track_Info object * */ //void scan_dir3(JNIEnv *env,jobject obj,const char *directory,jobjectArray list) void scan_dir3(JNIEnv *env,const char *directory,jobjectArray list) { DIR *dp; struct dirent *entry; struct stat statbuf; if((dp = opendir(directory)) == NULL) { perror("opendir"); return; } chdir(directory); jstring jstr; while ((entry = readdir(dp)) != NULL) { stat(entry->d_name, &statbuf); if (S_ISDIR(statbuf.st_mode)) { if ((strcmp(entry->d_name, ".") != 0) && (strcmp(entry->d_name, "..") != 0) && (entry->d_name[0] != '.')) { scan_dir3(env,entry->d_name,list); } } else { int size = strlen(entry->d_name); if (entry->d_name[0] != '.' //隐藏文件 && (statbuf.st_size/1024) > 300 //大于300k,表示肯能有mp3文件(忽略 <300k的mp3) && strcmp((entry->d_name + (size - 4)) , ".mp3") == 0) { char* parentPath = (char*)malloc(1024); char* absolutePath = (char*)malloc(1024); //首先获取工作路径 getcwd(parentPath,1024); //LOGE("parentPath = %s \n", parentPath); strcpy(absolutePath,parentPath); char *p = "/"; absolutePath = strcat(absolutePath,p); absolutePath = strcat(absolutePath,entry->d_name); // jstring jstrDis = (*env)->NewStringUTF(env, entry->d_name); // (*env)->SetObjectField(env, obj, disName, jstrDis); // //// (*env)->SetLongField(env, obj, trackSize, statbuf.st_size/1024); // // jstring jstrExt = (*env)->NewStringUTF(env,"mp3"); // (*env)->SetObjectField(env, obj, extName, jstrExt); // // jstring jstrPath = (*env)->NewStringUTF(env,absolutePath); // (*env)->SetObjectField(env, obj, path, jstrPath); // // jstring jstrParentPath = (*env)->NewStringUTF(env,absolutePath); // (*env)->SetObjectField(env, obj, parent, jstrParentPath); jclass classTrackInfo = (*env)->FindClass(env,"com/coder80/scaner/Track_Info"); // 获取Track_Info类的构造函数ID jmethodID midInit = (*env)->GetMethodID(env,classTrackInfo,"<init>", "()V"); //构造Track_Info对象 jobject objTrackInfo = (*env)->NewObject(env,classTrackInfo,midInit); /*查找java中的setDisplayName方法的ID, * @para:obj Track_Info类的对象 * @para:setDisplayName为Java中的函数名称 * @(Ljava/lang/String;)V 表示String类型的参数。返回值V代表void * */ JavaMid = (*env)->GetMethodID(env,classTrackInfo,"setDisplayName","(Ljava/lang/String;)V"); if (JavaMid == NULL) { LOGE("pyb setDisplayName() fun not found!"); return; } jstring jstrDis = (*env)->NewStringUTF(env,entry->d_name); //执行setDisplayName方法 jstrDis --> displayName (*env)->CallVoidMethod(env,objTrackInfo,JavaMid,jstrDis); JavaMid = NULL; //************************************************ //查找java中的setSize方法的ID,J -----> long JavaMid = (*env)->GetMethodID(env,classTrackInfo,"setSize","(J)V"); if (JavaMid == NULL) { LOGE("pyb setSize() fun not found!"); return; } // jstring jstrDis = (*env)->NewStringUTF(env,entry->d_name); // //执行setSize方法 statbuf.st_size --> size (*env)->CallVoidMethod(env,objTrackInfo,JavaMid,statbuf.st_size); JavaMid = NULL; //end //查找java中的setExt方法的ID, JavaMid = (*env)->GetMethodID(env,classTrackInfo,"setExt", "(Ljava/lang/String;)V"); if (JavaMid == NULL) { LOGE("pyb setExt() fun not found!"); return; } jstring jstrExt = (*env)->NewStringUTF(env,"mp3"); //执行setExt方法 jstrExt --> ext (*env)->CallVoidMethod(env,objTrackInfo,JavaMid,jstrExt); JavaMid = NULL; //查找java中的setFilePath方法的ID, JavaMid = (*env)->GetMethodID(env,classTrackInfo, "setFilePath","(Ljava/lang/String;)V"); if (JavaMid == NULL) { LOGE("setFilePath() fun not found!"); return; } jstring jstrPath = (*env)->NewStringUTF(env,absolutePath); //执行setFilePath方法 jstrPath --> filePath (*env)->CallVoidMethod(env,objTrackInfo,JavaMid,jstrPath); JavaMid = NULL; //查找java中的setParentPath方法的ID, JavaMid = (*env)->GetMethodID(env,classTrackInfo, "setParentPath","(Ljava/lang/String;)V"); if (JavaMid == NULL) { LOGE("setParentPath() fun not found!"); return; } jstring jstrParentPath = (*env)->NewStringUTF(env,parentPath); //执行setParentPath方法 jstrParentPath --> parentPath (*env)->CallVoidMethod(env,objTrackInfo,JavaMid,jstrParentPath); JavaMid = NULL; (*env)->SetObjectArrayElement(env,list,i,objTrackInfo); // LOGE("scan_dir3(),i = %d,file absolutePath = %s \n\n",i, absolutePath); i++; free(parentPath); parentPath = NULL; free(absolutePath); absolutePath = NULL; } } } chdir(".."); closedir(dp); }
在C中调用Java方法,首先需要构建一个Java中类的实例。
//查找Track_Info类 jclass classTrackInfo = (*env)->FindClass(env,"com/coder80/scaner/Track_Info"); // 获取Track_Info类的构造函数ID jmethodID midInit = (*env)->GetMethodID(env,classTrackInfo,"<init>", "()V"); //构造Track_Info对象 jobject objTrackInfo = (*env)->NewObject(env,classTrackInfo,midInit);GetMethodID函数中参数值"<init>"表示Track_Info类默认的构造函数。之后开始调用setDisplayName()方法.
JavaMid = (*env)->GetMethodID(env,classTrackInfo,"setDisplayName","(Ljava/lang/String;)V"); if (JavaMid == NULL) { LOGE("pyb setDisplayName() fun not found!"); return; } jstring jstrDis = (*env)->NewStringUTF(env,entry->d_name); //执行setDisplayName方法 jstrDis --> displayName (*env)->CallVoidMethod(env,objTrackInfo,JavaMid,jstrDis); JavaMid = NULL;代码段中GetMethodID(env,classTrackInfo,"setDisplayName","(Ljava/lang/String;)V");
1."setDisplayName"表示java中的
public void setDisplayName(String displayName) { this.displayName = displayName; }2."(Ljava/lang/String;)V"中Ljava/lang/String;表示参数类型:String。V 表示 返回值类型
调用Java中的setSize函数。
//查找java中的setSize方法的ID,J -----> long JavaMid = (*env)->GetMethodID(env,classTrackInfo,"setSize","(J)V"); if (JavaMid == NULL) { LOGE("pyb setSize() fun not found!"); return; } // jstring jstrDis = (*env)->NewStringUTF(env,entry->d_name); // //执行setSize方法 statbuf.st_size --> size (*env)->CallVoidMethod(env,objTrackInfo,JavaMid,statbuf.st_size); JavaMid = NULL;代码段中:(*env)->GetMethodID(env,classTrackInfo,"setSize","(J)V"); 参数值"(J)V" J表示 java中的long类型数据。
public void setSize(long size) { // Log.e("Track_Info.java", "setSize() called in JNI, size = " + size); this.size = size; }jmethodID GetMethodID(JNIEnv *env, jclass clazz,const char *name, const char *sig);
参数const char *sig表示方法签名,有特定的格式:(param-type)ret-type,括号内表示该方法传入参数类型,后面的是返回类型
其中param-type和ret-type都是由特定符号组成,各java primitive type都有各自对应符号如下表。
例如,在本例中,需要调用 public native Track_Info[] getTracksArray(String dirPath);在JNI_OnLoad函数中可以看到
其signature就是 (Ljava/lang/String;)[Lcom/coder80/scaner/Track_Info;
Ljava/lang/String;表示参数类型
[Lcom/coder80/scaner/Track_Info;表示函数getTracksArray的返回值为对象数组。
另外千万别忘记L fully-qualified-class ; 这个格式后面的那个;号。
主要类代码如下:
package com.coder80.scaner; import java.io.File; import java.util.ArrayList; import java.util.List; import android.os.AsyncTask; import android.os.Bundle; import android.os.Environment; import android.app.Activity; import android.util.Log; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { private Button mbtn; private Button mbtnJava; private long mTime; private TextView mTextView; private File mSdcardFile; private String mFlagJava = "java"; private String mFlagC = "native"; private boolean mIsClick; //防止多次点击 private Track_Info mTrack; private List<Track_Info> mTrackList = new ArrayList<Track_Info>(); private Track_Info[] mTracks;// = new Track_Info[100]; // char[] a = new char[100]; private boolean mIsExit;//sdcard是否存在 private void log_msg(String msg) { if(true){ Log.e(getClass().getSimpleName(), msg); } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mIsClick = false; mIsExit = true; mTrack = new Track_Info(); mSdcardFile = Environment.getExternalStorageDirectory(); Log.e("pyb", " mSdcardFile = " + mSdcardFile.toString()); if (android.os.Environment.MEDIA_MOUNTED.equals(android.os.Environment .getExternalStorageState())) { mIsExit = true; } else { mIsExit = false; Toast.makeText(MainActivity.this, "SDCard不存在,请安装!",Toast.LENGTH_LONG).show(); } mbtn = (Button) findViewById(R.id.button1); mbtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub if (mIsExit) { if (!mIsClick){ mIsClick = true; Log.e("pyb", " in the JNI scaner"); new MyAsyncTask().execute(mFlagC); } }else { Toast.makeText(MainActivity.this, "SDCard不存在,请安装!",Toast.LENGTH_LONG).show(); } } }); mbtnJava = (Button) findViewById(R.id.btn2); mbtnJava.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Log.e("pyb", " in the Java scaner"); new MyAsyncTask().execute(mFlagJava); } }); mTextView = (TextView) findViewById(R.id.TextView02); } public void addList(Track_Info track){ mTrackList.add(track); } public class MyAsyncTask extends AsyncTask<String, Long, Object> { @Override protected void onPreExecute() { // TODO Auto-generated method stub super.onPreExecute(); } @Override protected void onPostExecute(Object result) { // TODO Auto-generated method stub super.onPostExecute(result); if(mTime < 1000){ mTextView.setText("花费时间: " + Long.toString(mTime) + " 毫秒"); }else{ mTime = mTime/1000; mTextView.setText("花费时间: " + Long.toString(mTime) + " 秒"); } mIsClick = false; } @Override protected Object doInBackground(String... params) { // TODO Auto-generated method stub String flag = params[0]; Log.e("pyb", " doInBackground called...flag = " + flag); long time1 = System.currentTimeMillis(); // scanDir(mSdcardFile.toString() + "/音乐"); if(flag.equals("java")){ getFiles(mSdcardFile); for(int i = 0;i< mTrackList.size();i++){ Log.e("pyb", "mTrackList[" +i+"] path = " + mTrackList.get(i).getFilePath()); } }else if(flag.equals("native")){ // scanDir(mSdcardFile.toString()); // array = getPathArray(mSdcardFile.toString()); mTracks = getTracksArray(mSdcardFile.toString()); Log.e("pyb", "mTracks.length = "+ mTracks.length); for (int i = 0; i < mTracks.length; i++) { if (mTracks[i] != null) { Log.e("pyb", "mTracks[" +i+"] path = " + mTracks[i].getFilePath()); } else { Log.e("pyb", "mTracks == null"); break; } } } long time2 = System.currentTimeMillis(); mTime = time2 - time1; Log.e("pyb", "in the doInBackground(),scaner mp3 cost time = " + (time2 - time1) ); return null; } }; @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } static { Log.e("pyb", " System.loadLibrary() called..."); System.loadLibrary("scan"); } /** * 获取音乐文件列表 * @param filePath */ public void getFiles(File filePath) { File[] files = filePath.listFiles(); if (files != null) { for (int i = 0; i < files.length; i++) { if (files[i].isDirectory() && !files[i].isHidden() && files[i].canRead()) { getFiles(files[i]); } else { // Mp3support String displayName = files[i].getName(); if (displayName.endsWith(".mp3") || displayName.endsWith(".MP3")) { // String[] strarray = displayName.split("\\."); // String path = files[i].getParentFile().toString(); String fileName = files[i].getName(); String[] strarray=fileName.split("\\."); // String displayName = strarray[0]; String ext = strarray[1]; String filepath = files[i].toString(); String parentPath = files[i].getParentFile().toString() + "/"; mTrack = new Track_Info(); mTrack.setDisplayName(displayName); mTrack.setExt(ext); mTrack.setFilePath(filepath); mTrack.setParentPath(parentPath); mTrackList.add(mTrack); } } } } } public native void scanDir(String dirPath); public native String[] getPathArray(String dirPath); public native Track_Info[] getTracksArray(String dirPath); }
通过本例,可以了解JNI使用方法,对稍微复杂的JNI编程,例如从native层调用Java层对象的讲解,是有一定的帮助的。
demo代码已经上传到博客资源中!