声明

  欢迎转载,但请保留文章原始出处:) 

    博客园:http://www.cnblogs.com

    kchen http://www.cnblogs.com/kchen/

      新浪微博:http://weibo.com/kchen30 

 

 

在这里,先简单介绍一下Android NDKjni

 

NDK:可以参照~

http://baike.baidu.com/view/5236494.htm

简单来说,NDK就是提供了一个在Android平台上使用c/c++的一个平台,结合IDE,可以轻松快捷的将c/c++源码编译成so文件,并打包进android应用程序的apk里,并提供一堆Android程序特有的库。

 

JNI:可以参照~

http://baike.baidu.com/view/1272329.htm

简单来说,JNI就是允许java代码与其他语言写的代码交互,尤其是为CC++而设计的。

 

开始步骤:可以参照~

ANDROID: NDK编程入门笔记

http://www.cnblogs.com/hibraincol/archive/2011/05/30/2063847.html

搭建好开发环境,并完成hello world之后,就可以开发自己需要的jni应用程序了

 

注:搭建ndk编译环境,有一些问题

Windows平台: 需要安装通过cygwin来模拟linux环境,并且通过linuxgcc来编译

Linux平台:在官网下载好android ndk安装包后,根据帮助一步步安装即可

Mac平台:mac os x虽然是基于unix的,但是默认情况下是不提供开发工具的,也木有gcc 之类的编译工具,开发人员需要先安装xcode以后,才能使用android ndk

 

下面我们说说javac/c++之间调用的问题

Java调用c/c++

 先看例子

 

public class Sample1
{
   
public native int intMethod(int n);
   
public native boolean booleanMethod(boolean bool);
   
public native String stringMethod(String text);
   
public native int intArrayMethod(int[] intArray);

   
public static void main(String[] args)
   {
     System.loadLibrary(
"Sample1");
     Sample1 sample 
= new Sample1();
     
int     square = sample.intMethod(5);
     
boolean bool   = sample.booleanMethod(true);
     String  text   
= sample.stringMethod("JAVA");
     
int     sum    = sample.intArrayMethod(
                         
new int[]{1,1,2,3,5,8,13} );

     System.out.println(
"intMethod: " + square);
     System.out.println(
"booleanMethod: " + bool);
     System.out.println(
"stringMethod: " + text);
     System.out.println(
"intArrayMethod: " + sum);
   }

} 

 

 然后编译,编译完成以后,可以通过javah 工具所生成的 C/C++ 头文件

 

 /* DO NOT EDIT THIS FILE - it is machine generated */

#include <jni.h>
/* Header for class Sample1 */

#ifndef _Included_Sample1
#define _Included_Sample1
#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jint JNICALL Java_Sample1_intMethod
   (JNIEnv 
*, jobject, jint);

 JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod
   (JNIEnv 
*, jobject, jboolean);
 
 JNIEXPORT jstring JNICALL Java_Sample1_stringMethod
  (JNIEnv 
*, jobject, jstring);

 JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod
  (JNIEnv 
*, jobject, jintArray);
 
 #ifdef __cplusplus
 }
 
#endif
 
#endif

 

 C 函数实现

 #include "Sample1.h"

 #include <string.h>
 
 JNIEXPORT jint JNICALL Java_Sample1_intMethod
   (JNIEnv 
*env, jobject obj, jint num) {
    
return num * num;
 }
 
 JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod
   (JNIEnv 
*env, jobject obj, jboolean boolean) {
   
return !boolean;
 }

 JNIEXPORT jstring JNICALL Java_Sample1_stringMethod
   (JNIEnv 
*env, jobject obj, jstring string) {
     
const char *str = (*env)->GetStringUTFChars(env, string0);
     
char cap[128];
     strcpy(cap, str);
     (
*env)->ReleaseStringUTFChars(env, string, str);
     
return (*env)->NewStringUTF(env, strupr(cap));
 }
 
 JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod
   (JNIEnv 
*env, jobject obj, jintArray array) {
     
int i, sum = 0;
     jsize len 
= (*env)->GetArrayLength(env, array);
     jint 
*body = (*env)->GetIntArrayElements(env, array, 0);
     
for (i=0; i<len; i++)
     {    sum 
+= body[i];
     }
     (
*env)->ReleaseIntArrayElements(env, array, body, 0);
     
return sum;
 }
 
 
void main(){}

 

 c++函数实现

 

 #include "Sample1.h"

 #include <string.h>

JNIEXPORT jint JNICALL Java_Sample1_intMethod
  (JNIEnv 
*env, jobject obj, jint num) {
   
return num * num;
 }

 JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod
   (JNIEnv 
*env, jobject obj, jboolean boolean) {
   
return !boolean;
 }

 JNIEXPORT jstring JNICALL Java_Sample1_stringMethod
   (JNIEnv 
*env, jobject obj, jstring string) {
     
const char *str = env->GetStringUTFChars(string0);
     
char cap[128];
     strcpy(cap, str);
     env
->ReleaseStringUTFChars(string, str);
     
return env->NewStringUTF(strupr(cap));
 }
 
 JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod
   (JNIEnv 
*env, jobject obj, jintArray array) {
     
int i, sum = 0;
     jsize len 
= env->GetArrayLength(array);
     jint 
*body = env->GetIntArrayElements(array, 0);
     
for (i=0; i<len; i++)
     {    sum 
+= body[i];
     }
     env
->ReleaseIntArrayElements(array, body, 0);
     
return sum;
 }

 
void main(){}

 

 

 注:c和c++实现的方式略微不同
C 语法:         jsize len = (*env)->GetArrayLength(env,array);
C++ 语法:       jsize len =env->GetArrayLength(array);

 

 

c/c++调用Java

先看例子
public class Sample2
 {
   
public static int intMethod(int n) {
       
return n*n;
   }

   
public static boolean booleanMethod(boolean bool) {
        
return !bool;
   }
 }

 

 再看c的调用方式

 

 #include <jni.h>


 #ifdef _WIN32
 
#define PATH_SEPARATOR ';'
 
#else
 
#define PATH_SEPARATOR ':'
 
#endif

 
int main()
 {
   JavaVMOption options[
1];
   JNIEnv 
*env;
   JavaVM 
*jvm;
   JavaVMInitArgs vm_args;
   
long status;
   jclass cls;
   jmethodID mid;
   jint square;
   jboolean not;

   options[
0].optionString = "-Djava.class.path=.";
   memset(
&vm_args, 0sizeof(vm_args));
   vm_args.version 
= JNI_VERSION_1_2;
   vm_args.nOptions 
= 1;
   vm_args.options 
= options;
   status 
= JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

   
if (status != JNI_ERR)
   {
     cls 
= (*env)->FindClass(env, "Sample2");
     
if(cls !=0)
     { mid 
= (*env)->GetStaticMethodID(env, cls, "intMethod""(I)I");
       
if(mid !=0)
       { square 
= (*env)->CallStaticIntMethod(env, cls, mid, 5);
                printf(
"Result of intMethod: %d\n", square);
       }

       mid 
= (*env)->GetStaticMethodID(env, cls, "booleanMethod""(Z)Z");
       
if(mid !=0)
      { not 
= (*env)->CallStaticBooleanMethod(env, cls, mid, 1);
         printf(
"Result of booleanMethod: %d\n", not);
       }
     }

     (
*jvm)->DestroyJavaVM(jvm);
     
return 0;
   }
   
else
   
return -1;
 }

 

 再看c++的调用例子

 #include <jni.h>


 #ifdef _WIN32
 
#define PATH_SEPARATOR ';'
 
#else
 
#define PATH_SEPARATOR ':'
 
#endif

 
int main()
 {
      JavaVMOption options[
1];
      JNIEnv 
*env;
      JavaVM 
*jvm;
      JavaVMInitArgs vm_args;
      
long status;
      jclass cls;
      jmethodID mid;
      jint square;
      jboolean not;

      options[
0].optionString = "-Djava.class.path=.";
      memset(
&vm_args, 0sizeof(vm_args));
      vm_args.version 
= JNI_VERSION_1_2;
      vm_args.nOptions 
= 1;
      vm_args.options 
= options;
      status 
= JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

      
if (status != JNI_ERR)
   {
        cls 
= (*env)->FindClass(env, "Sample2");
        
if(cls !=0)
     {   mid 
= (*env)->GetStaticMethodID(env, cls, "intMethod""(I)I");
            
if(mid !=0)
            {  square 
= (*env)->CallStaticIntMethod(env, cls, mid, 5);
               printf(
"Result of intMethod: %d\n", square);
            }

            mid 
= (*env)->GetStaticMethodID(env, cls, "booleanMethod""(Z)Z");
            
if(mid !=0)
            {  not 
= (*env)->CallStaticBooleanMethod(env, cls, mid, 1);
               printf(
"Result of booleanMethod: %d\n", not);
            }
     }

        (
*jvm)->DestroyJavaVM(jvm);
    
return 0;
   }
      
else
        
return -1;
 }

 

C 语法: cls = (*env)->FindClass(env, "Sample2");

C++ 语法: cls = env->FindClass("Sample2");

 

 先简单介绍到这里,下次再说


posted @ 2011-08-03 12:21 kchen 阅读(167) 评论(1) 编辑

声明

  欢迎转载,但请保留文章原始出处:) 

    博客园:http://www.cnblogs.com

    kchen: http://www.cnblogs.com/kchen/

新浪微博:http://weibo.com/kchen30 

 

自从06年以后,就没有写过博客了,不是因为没时间,而是因为懒了,现在又重新拾起来,有些感触。

 

先说说View的界面原理吧

 

一个Activity大致是这样的结构,当界面发生变化的时候(比如动画,点击,滚动条滚动,界面刷新)都需要一层层的重绘界面,最终将所有VISIBLE显示的VIEW全部重绘为止,也就是说,当滚动条从滚动的时候,会调用NVIEWonMeasure, dispatchDraw,onDraw方法,其中如果当前VIEW有背景的情况下,那么会调用onDrawdispatchDraw方法,如果没有背景,那么只调用dispatchDraw方法。

 

所以,想要提高UI的性能,首先需要做的事情,就是减少不必要的onMeasure,dispatchDraw,onDraw调用。

 

打个比方,当通过调用Viewlayout方法来实现VIEW在界面上覆盖时,尽量将被遮住的VIEW隐藏起来,特别是一些绘制起来比较大的VIEW,如ListView,GridView等。

 

下面再谈谈ListViewGridView的性能优化

1、关于Google IO大会关于Adapter的优化,参考以下文章:

      Android开发之ListView 适配器(Adapter)优化

      Android开发——09Google I/O之让Android UI性能更高效(1)

2、在这里我要说的是另一种方法

 

 private class MyAdapter extends BaseAdapter{

        ArrayList<String> List;
        Context ctx;
        
public BookAdapter(Context c,ArrayList<String> list){
            List 
= list;
            ctx 
= c;
            BuildViewList();
        }
        
        View[] viewList;
        
        
private void BuildViewList()
        {
            viewList 
= new View[List.size()];
        }
        
        @Override
        
public int getCount() {
            
return List.size();
        }

        @Override
        
public Object getItem(int position) {
            
// TODO Auto-generated method stub
            return position;
        }

        @Override
        
public long getItemId(int position) {
            
// TODO Auto-generated method stub
            return position;
        }

        @Override
        
public View getView(int position, View convertView, ViewGroup parent) {
            View layout 
= viewList[position];
            
//如果该View没有初始化,那么初始化它,并且放入缓存数组
            if (layout == null)
            {
                
final LayoutInflater inflater = LayoutInflater.from(ctx);
                
// 给ImageView设置资源
                layout = (LinearLayout)inflater.inflate(R.layout.listitem, null);
                                
                TextView txtName 
= (TextView)layout.findViewById(R.id.txtBookName);
                txtName.setText(List.get(position))
                viewList[position] 
= layout;
            }
            
return layout;
        }
        
    }

 

 这种方式可以有效的减少inflatefindViewById的性能开销,并且不需要每次都重新给View赋值,

 

3、关于fill_parent和wrap_content,fill_parent比wrap_content的性能高很多,尽量使用fill_parent,具体原因下次写

 

先写这么多,以后继续写。

posted @ 2011-08-02 13:36 kchen 阅读(245) 评论(2) 编辑
在VS2003里面,如果要在DataList的每一个item都加上一些属性,我想是可以这样的:
在DataList1_ItemDataBound这个事件里加上
if (e.Item.ItemType == ListItemType.Item)
{
 e.Item.Attributes.Add("onclick", "javascript:alert('sdfsss');");
} 这些语句。
然后在显示的页面上点击每一个datalist的item的时候,就会弹出一个alert。
 但是在VS2005里面,我同样的做法却没有任何效果。
但是VS2005里,对GridView如果
 protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            e.Row.Attributes.Add("onclick", "javascript:alert('sdfsdf');");
        }
    }
这样做,点击每一行的时候是可以弹出alert的。
我的问题是,为什么在VS2005里DataList不能这样实现效果,或者有没有别的办法可以实现点击每个Item,
让他弹出一个alert(关于用findcontrol找到item里面的控件,然后绑定事件,这样做也是可以的,但是
不是我想要的效果,我想要的效果是,点击item的每一个地方,都可以有事件触发)
我想请问一下大家有遇到过这样的问题吗,麻烦帮忙解惑一下。
posted @ 2006-12-18 13:16 kchen 阅读(595) 评论(1) 编辑
摘要: 最近在做一个自定义控件,发生了一个问题,就是在OnPreRender()的时候,需要注册客户端脚本,往往会在控件里加一个属性,设置javascript文件*.js的路径,在使用控件时,页面有可能放到n层的目录底下,有的页面在最上层的目录底下,而每个页面都要修改一下路径,会很麻烦,所以我打算把js封装到dll中。
在custom control的class中,写一个BuildScriptCode()的方法,以下是代码阅读全文
posted @ 2006-11-21 16:29 kchen 阅读(254) 评论(0) 编辑
摘要: 事情是这样的,最近正在做一个Custom DataGrid Control的时候,在分页的情况下,删除最后一条纪录,再次DataBind的时候,CurrentPageIndex属性会大于PageCount,于是,在DataGrid自身OnDataBinding(EventArgs e)方法中,会抛出一个CurrentPageIndex must <= PageCount的异常,但是由于在OnDataBinding(EventArgs e)绑定前,PageCount是从Post过来的ViewState中Load的,所以,当数据改变后,不会有变化,所以,我们必须重新计算PageCount,下面是重新计算PageCount的方法阅读全文
posted @ 2006-11-20 20:08 kchen 阅读(290) 评论(0) 编辑
摘要: 写了一个对象集合排序的类阅读全文
posted @ 2006-11-05 14:58 kchen 阅读(1260) 评论(8) 编辑
摘要: 我们在平时使用数据库的时候,经常会碰到一个问题,就是不希望数据实体对象插入数据库中, 却有想持久化的时候,那么就可以用序列化成

XML字符串,来保存到其他地方,由于生成的是字符串,所以可以保存到任意我们想保存的地方。比如 asp.net的ViewState,cookie,cache等
阅读全文
posted @ 2006-11-04 23:20 kchen 阅读(2510) 评论(5) 编辑
摘要: 关于Assembly.CreateInstance()与Activator.CreateInstance()方法的区别

呃``最近用惯了Activator.CreateInstance()和Activator.CreateInstance(),非常好用,可是在看许多别人的源代码的时候,大多数用了Assembly.Load("AssemblyName").CreateInstance("ClassName");的方法,忽然想研究一下这两者到底有什么区别,于是,打开msdn,查到了两个方法的介绍:

Assembly.CreateInstance 方法 (String)

使用区分大小写的搜索,从此程序集中查找指定的类型,然后使用系统激活器创建它的实例。

Activator.CreateInstance 方法 (Type)

使用与指定参数匹配程度最高的构造函数来创建指定类型的实例。

看完以后,忽然觉得说了跟没说一样。不知道是我文字理解能力有问题,还是它表达有问题。
阅读全文
posted @ 2006-11-02 21:23 kchen 阅读(9057) 评论(2) 编辑
摘要: 花了几个小时,把我的每天记帐的程序改成多语言版本的了~~~

Asp.net 2.0提供了本地化多语言版本的一些方便的特性,网上关于这个的文章已经很多了,我在此就不用多说拉,我只是说说,我在做的时候碰到的一些问题,以及如何解决的。

事情是这样的,把一个已经做的差不多的项目改成多语言版本,大概有以下几部:
1、在BasePage类中写以下代码(就是每个page需要继承的公共page)

protected override void InitializeCulture()
{
//State是自己写的一个全局变量,写到Cookie里的
if (this.State["UICulture"] != null)
{
if (this.State["UICulture"] != string.Empty)
Page.U阅读全文
posted @ 2006-11-01 23:17 kchen 阅读(677) 评论(0) 编辑
摘要: 呃```花了一晚上时间,终于搞出来了如何通过反射,从DataReader将数据填充到数据实体泛型集合的静态方法.//Kchen.Core.BaseBusinessObject为通用数据实体类,此处仅为限定T所继承的类型publicstaticIList<T>FillDataListGeneric<T>(System.Data.IDataReaderreader)whereT...阅读全文
posted @ 2006-10-31 00:02 kchen 阅读(2391) 评论(11) 编辑

公告

新浪微博:

http://weibo.com/kchen30

昵称:kchen
园龄:5年8个月
粉丝:5
关注:1
<2012年1月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
2930311234