上篇中简单介绍了,java中的类型和C中的类型的映射的,本篇将以一个无聊的实例来看看JNI中数组的使用。
皇后的祝福,思路很简单,就是利用我们耳熟能详的把皇后问题结合JNI来实现一点点小小的乐趣,在快乐中学习JNI。。。。
1、用C语言实现八皇后的算法,我们知道八皇后有92种解,每种解是一个数据,对应这当前这组解中八个皇后的位置。
2、在java中通过JNI调用c中的方法,获取八皇后的解。
3、在java端完成一些随机性的提示信息。
本篇的源码大家可以到eoe去下载:
http://www.eoeandroid.com/thread-75221-1-1.html
下面请看代码:
1、首先,在java端定义一个接口Queen.java,只有一个方法,简单的很:
- public class Queen {
- public native int[][] getResult();
- }
2、利用javah生成c语言的头文件,此处略过。
3、在C中实现逻辑:
- #include <stdlib.h>
- #include <stdio.h>
- #include <math.h>
- #include <org_liner_queen_Queen.h>
- /*
- * 求八皇后的解
- */
- void queen(int results[][8])
- {
- int queens[8];
- int k=0;
- int currIndex = 0;
- queens[k]=-1;
- while(k>=0)
- {
- queens[k]=queens[k]+1;
- while(queens[k]<8 && !place(k, queens))
- {
- queens[k]=queens[k]+1;
- }
- if(queens[k]<8)
- {
- if(k == 7)
- {
- int i;
- for(i=0; i<8; i++)
- {
- results[currIndex][i] = queens[i];
- }
- currIndex++;
- }else
- {
- k++;
- queens[k]=-1;
- }
- }
- else
- {
- k--;
- }
- }
- return;
- }
- int place(int k, int* queens)
- {
- int i;
- for(i=0; i<k; i++)
- {
- if(queens[i] == queens[k] || abs(queens[i]-queens[k])==abs(i-k))
- {
- return 0;
- }
- }
- return 1;
- }
- //java端生成的方法
- JNIEXPORT jobjectArray JNICALL Java_org_liner_queen_Queen_getResult
- (JNIEnv *env, jobject thiz)
- {
- int i=0;
- jobjectArray result;
- int results[92][8];
- queen(results);//获取92种解
- jclass cls = (*env)->FindClass(env,"[I"); //寻找java中int[]类型
- if(cls == NULL)
- {
- return NULL;
- }
- //二维数组其实就是一个一维对象数组,每个元素就是一个数组对象
- //调用该接口方法实例化一个对象数组,大小92
- result = (*env)->NewObjectArray(env, 92, cls, NULL);
- if(result == NULL)
- {
- return NULL;
- }
- //将92种解对应的每一维的数组,赋值到result
- for(i=0; i<92; i++)
- {
- jint temp[8];
- int j;
- jintArray iarr = (*env)->NewIntArray(env,8); //实例化一个一维的int类型的数组,大小为8
- if(iarr == NULL)
- {
- return NULL;
- }
- for(j=0; j<8;j++)
- {
- temp[j]=results[i][j];
- }
- (*env)->SetIntArrayRegion(env, iarr, 0, 8, temp); //给数组赋值
- (*env)->SetObjectArrayElement(env, result, i, iarr);//给对象数组赋值,单个元素
- (*env)->DeleteLocalRef(env, iarr); //释放刚刚实例化的数组
- }
- return result;
- }
4、在java端的处理:
- package org.liner.queen;
- import org.liner.queen.Tips.Tip;
- import android.app.Activity;
- import android.content.ContentResolver;
- import android.content.ContentValues;
- import android.content.Context;
- import android.database.Cursor;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.AdapterView;
- import android.widget.BaseAdapter;
- import android.widget.Button;
- import android.widget.GridView;
- import android.widget.ImageView;
- import android.widget.Toast;
- public class MainActivity extends Activity {
- static{
- System.loadLibrary("org_liner_queen_Queen");
- }
- public static final int MAX_RESULT_INDEX = 92;//92种解
- public static final int COLUMN_NUM = 8;
- private GridView chessboard;
- private Button btnPre,btnNext;
- private int currResultIndex = 0;
- private int theQueenIndex;
- //棋盘
- private Integer picIds[] = {
- R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,
- R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,
- R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,
- R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,
- R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,
- R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,
- R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,
- R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black,R.drawable.white,R.drawable.black
- };
- //全部解2*8+7=23
- private int[][] results;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- //btnFirst = (Button)this.findViewById(R.id.btn_first);
- btnPre = (Button)this.findViewById(R.id.btn_pre);
- btnNext = (Button)this.findViewById(R.id.btn_next);
- //btnLast = (Button)this.findViewById(R.id.btn_last);
- _initData();
- _init();
- }
- private void _showGrid(){
- chessboard = (GridView)this.findViewById(R.id.chessboard);
- chessboard.setAdapter(new GridAdapter(this));
- chessboard.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View v, int position,
- long id) {
- // 单击事件,判断当前单击的是否是皇后所在的位置,如果是,则判断当前皇后是否
- //是给出祝福的皇后,如果是,则随机选择一个祝福语;否则,则选择一个提示语
- //对于非皇后的位置,如果用户点击,则
- _tip(position);
- }
- });
- }
- private int getRandom(int maxValue){
- return (int)(Math.random()*maxValue);
- }
- private int getTheQueenIndex(){
- Log.v("Result:::", results.length+"");
- int col = this.getRandom(COLUMN_NUM);
- return col*COLUMN_NUM + results[currResultIndex][col];//将二维的转换成一维对应的位置
- }
- private void _tip(int position){
- int type;
- if(picIds[position] == R.drawable.bqueen || picIds[position]==R.drawable.wqueen){
- if(position == theQueenIndex){
- //是送祝福的皇后
- type=2;
- }else{
- //不是送祝福的皇后
- type = 1;
- }
- }else{
- //不是皇后
- type = 0;
- }
- String[] projection = new String[]{
- Tip._ID,
- Tip.CONTENT,
- Tip.TYPE
- };
- String selection = Tip.TYPE+"=?";
- String[] selectionArgs = new String[]{
- type+""
- };
- Cursor cursor = this.getContentResolver().query(Tip.CONTENT_URI, projection, selection, selectionArgs, null);
- //在所有的数据中随机抽取一条
- if(cursor.moveToFirst()){
- int rand = this.getRandom(cursor.getCount());
- cursor.moveToPosition(rand);
- String tip = cursor.getString(cursor.getColumnIndexOrThrow(Tip.CONTENT));
- Toast.makeText(this, tip, Toast.LENGTH_LONG).show();
- }
- cursor.close();
- }
- private void _initData(){
- TipDBHelper db = new TipDBHelper(this);
- db.onUpgrade(db.getWritableDatabase(), TipDBHelper.VERSION, TipDBHelper.VERSION+1);
- ContentValues values = new ContentValues();
- String[] tip0 = new String[]{
- "不要乱点哦!",
- "真无聊!",
- "呵呵,你真的好搞笑哦!",
- "不要这么无聊哦!",
- "点皇后,你点我干什么!",
- "嘿嘿,好痒哦!",
- "你真的笨的可以哦,点皇后嘛!",
- "再乱点,小心我揍你哦!"
- };
- String[] tip1 = new String[]{
- "皇后现在不在,去洗澡了!",
- "皇后正在休息,稍后再来哦!",
- "皇后正在看电视,她最讨厌别人打扰了,小心砍你头哦!",
- "皇后去游御花园了,你可以去那找她!",
- "皇帝来了,他们正在...",
- "皇后正在洗澡,一会再来哦!",
- "皇后去太后那里请安了!",
- "皇后正在化妆,别打扰!"
- };
- String[] tip2 = new String[]{
- "恭喜!皇后祝您身体健康,事事如意!",
- "恭喜!皇后祝您梦想成真!",
- "恭喜!皇后约你夜半三更后花园见!",
- "恭喜!皇后说今天你买彩票可以中五百万!",
- "恭喜!皇后说要给你一百万两银子!",
- "恭喜!皇后偷偷地说:她喜欢你..."
- };
- String[][] tips = new String[][]{
- tip0,tip1,tip2
- };
- for(int i=0; i<tips.length; i++){
- for(int j=0; j<tips[i].length; j++){
- values.put(Tip.CONTENT, tips[i][j]);
- values.put(Tip.TYPE, i);
- this.getContentResolver().insert(Tip.CONTENT_URI, values);
- }
- }
- }
- //初始化方法,
- private void _init(){
- currResultIndex=0;
- Queen queen = new Queen();
- results = queen.getResult(); //调用JNI,获取八皇后问题的解,初始化results数组
- _placeQueens();
- //_showGrid();
- }
- private void _placeQueens(){
- theQueenIndex = this.getTheQueenIndex();//随机取得送祝福的皇后
- int[] currResult = results[currResultIndex];
- for(int i=0; i<currResult.length; i++){
- int rIndex = i*COLUMN_NUM+currResult[i]; //计算当前皇后在棋盘中的位置
- if((rIndex/COLUMN_NUM)%2==0){
- //黑白
- if((rIndex%COLUMN_NUM)%2 == 0){
- //当前是黑色
- picIds[rIndex] = R.drawable.bqueen;
- }else{
- picIds[rIndex] = R.drawable.wqueen;
- }
- }else{
- //白黑
- if((rIndex%COLUMN_NUM)%2 == 0){
- //当前是白色
- picIds[rIndex] = R.drawable.wqueen;
- }else{
- picIds[rIndex] = R.drawable.bqueen;
- }
- }
- }
- //chessboard.removeAllViews();
- _showGrid();
- }
- private void _removeQueens(int index){
- int[] currResult = results[index];
- for(int i=0; i<currResult.length; i++){
- int rIndex = i*COLUMN_NUM+currResult[i]; //计算当前皇后在棋盘中的位置
- if((rIndex/COLUMN_NUM)%2==0){
- //黑白
- if((rIndex%COLUMN_NUM)%2 == 0){
- //当前是黑色
- picIds[rIndex] = R.drawable.black;
- }else{
- picIds[rIndex] = R.drawable.white;
- }
- }else{
- //白黑
- if((rIndex%COLUMN_NUM)%2 == 0){
- //当前是白色
- picIds[rIndex] = R.drawable.white;
- }else{
- picIds[rIndex] = R.drawable.black;
- }
- }
- }
- //chessboard.removeAllViews();
- //_showGrid();
- }
- private void _first(){
- _removeQueens(currResultIndex);
- this.currResultIndex = 0;
- _placeQueens();
- btnPre.setEnabled(false);
- btnNext.setEnabled(true);
- }
- private void _pre(){
- _removeQueens(currResultIndex);
- this.currResultIndex--;
- if(currResultIndex ==0){
- btnPre.setEnabled(false);
- }
- btnNext.setEnabled(true);
- _placeQueens();
- }
- private void _next(){
- _removeQueens(currResultIndex);
- this.currResultIndex++;
- if(currResultIndex == MAX_RESULT_INDEX-1){
- btnNext.setEnabled(false);
- }
- btnPre.setEnabled(true);
- _placeQueens();
- }
- private void _last(){
- _removeQueens(currResultIndex);
- this.currResultIndex=MAX_RESULT_INDEX-1;
- btnNext.setEnabled(false);
- btnPre.setEnabled(true);
- _placeQueens();
- }
- public void onClic(View v){
- int id = v.getId();
- switch(id){
- case R.id.btn_first:
- _first();
- break;
- case R.id.btn_pre:
- _pre();
- break;
- case R.id.btn_next:
- _next();
- break;
- case R.id.btn_last:
- _last();
- break;
- }
- }
- /**
- * GridView中每一个View需要是一个ImageView
- * @author chenjie
- *
- */
- public class GridAdapter extends BaseAdapter{
- private Context context;
- public GridAdapter(Context context){
- this.context = context;
- }
- @Override
- public int getCount() {
- // TODO Auto-generated method stub
- return picIds.length;
- }
- @Override
- public Object getItem(int position) {
- // TODO Auto-generated method stub
- return picIds[position];
- }
- @Override
- public long getItemId(int position) {
- // TODO Auto-generated method stub
- return position;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- ImageView imageView;
- if(convertView == null){
- imageView = new ImageView(context);
- imageView.setLayoutParams(new GridView.LayoutParams(40, 40));
- imageView.setAdjustViewBounds(false);
- imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
- imageView.setPadding(2, 2, 2, 2);
- }else{
- imageView = (ImageView)convertView;
- }
- imageView.setImageResource(picIds[position]);
- return imageView;
- }
- }
- }
5、效果预览: