任何问题请联系WX:uu16853

买模板送网站采集器 让你轻松放开双手运营网站!

购买更多有优惠!

Android ANR介绍与避免 Android开发技术

  很多初入Android开发的网友可能发现ANR的字样,到底Android ANR是什么呢? 其实ANR就是Application Not Responding的全称,当某个应用处于长期假死状态时Android系统会弹出一个窗口上面写道,XXX is not responding给出两个按钮一个为force close一个为wait。    可能触发ANR的情况   1. 长时间的I/O处理,比如读写大文件,网络访问时造成的阻塞。   2. 执行耗时的运算,Android默认为超过5000ms即5秒开始弹出ANR窗口,某些应用可能首次执行时没有缓存十分耗时,可以通过Splash播放闪屏Logo等方式来延缓加载   3. Service和appWidget中也要注意多线程的使用,除非它和Activity工作在不同的进程。   避免ANR的方法  1. 单独开工作者线程,通过独立的Thread或使用类似AsyncTask的方式来处理耗时的内容。  2. 耗时的操作尽量分段处理,使用类似状态机的方法,类似Symbian的活动对象将一个复杂的事情,分段执行。  3. UI线程中不要处理过多的内容,比如将一个5MB的文本,让TextView去setText,要知道这种UI操作,没有什么好方法去解决的,所以Android123提示,遇到UI中需要执行复杂的操作,可以参考上面2提到的分段处理方式。

Android JSON解析示例代码 Android开发技术

  来自Google官方的有关Android平台的JSON解析示例,如果远程服务器使用了json而不是xml的数据提供,在Android平台上已经内置的org.json包可以很方便的实现手机客户端的解析处理。下面Android123一起分析下这个例子,帮助Android开发者需要有关 HTTP通讯、正则表达式、JSON解析、appWidget开发的一些知识。 public class WordWidget extends AppWidgetProvider { //appWidget    @Override    public void onUpdate(Context context, AppWidgetManager appWidgetManager,            int[] appWidgetIds) {         context.startService(new Intent(context, UpdateService.class)); //避免ANR,所以Widget中开了个服务    }     public static class UpdateService extends Service {        @Override        public void onStart(Intent intent, int startId) {            // Build the widget update for today            RemoteViews updateViews = buildUpdate(this);             ComponentName thisWidget […]

获取Android手机上的图片和视频缩略图 Android开发技术

   大家都知道Android从1.5开始刚插入SD卡时系统会调用MediaScanner服务进行后台扫描,索引新的歌曲、图片和视频等信息,如果我们需要快速提取图片和视频缩略图可以直接访问 android.provider.MediaStore.Images.Thumbnails 和android.provider.MediaStore.Video.Thumbnails这两个数据库,即可查询出来缩略图   如何判断文件呢? 可以通过Cursor遍历数据库,对比INTERNAL_CONTENT_URI字段的值,这是一个Uri我们可以转成String,这里保存着Android手机SD卡上的多媒体文件完整路径,   有关具体的缩略图可以通过getThumbnail(ContentResolver cr, long origId, int kind, BitmapFactory.Options options) 或getThumbnail(ContentResolver cr, long origId, long groupId, int kind, BitmapFactory.Options options) 方法获取,这两种方法返回Bitmap类型,而缩略图的分辨率可以从HEIGHT和WIDTH两个字段提取,在Android上缩略图分为两种,通过读取KIND字段来获得,分别为MICRO_KIND和MINI_KIND 分别为微型和迷你两种缩略模式,前者的分辨率更低。这样我们平时获取文件系统的某个图片预览时,可以直接调用系统缩略图,而不用自己重新计算。   最后Android123提示大家,缩略图保存在SD卡的DCIM目录,里面的.thumbnails是图片的,而.video_thumbnails是视频的,这两个文件夹为隐藏属性,一般的文件管理器都可以看到。

Android上鲜为人知的UI控件介绍和使用 Android开发技术

  很多Android应用开发者可能习惯了常见的ListView和GirdView其实,Google还提供了一些不错的UI控件,丰富了Android应用的UI显示,只要了解View和Adapter之间的关系,相信你可以很方便的了解每个种控件的使用和扩展,今天Android123一起来谈下,鲜为人知的Android UI控件。   1. SlidingDrawer 抽屉式滑动控件   在Android 1.x时代,功能表是通过Home Screen底部的一个按钮,可以拖拉出来一个View,这种控件其实Android上从1.5开始加入,使用时直接在layout中定义即可,xml布局代码如下: 当然了下面的match_parent就是fill_parent在2.2中被重命名了   <SlidingDrawer     android:id="@+id/drawer"     android:layout_width="match_parent"     android:layout_height="match_parent"      android:handle="@+id/handle"     android:content="@+id/content">      <ImageView         android:id="@id/handle"         android:layout_width="88dip"         android:layout_height="44dip" />      <GridView         android:id="@id/content"         android:layout_width="match_parent"         android:layout_height="match_parent" />  </SlidingDrawer>   有关控制,大家可以看下Android 1.5或1.6的Launcher源码,这里SlidingDrawer主要实现了void  setOnDrawerCloseListener(SlidingDrawer.OnDrawerCloseListener onDrawerCloseListener) 和 void  setOnDrawerOpenListener(SlidingDrawer.OnDrawerOpenListener onDrawerOpenListener) 以及 void  setOnDrawerScrollListener(SlidingDrawer.OnDrawerScrollListener onDrawerScrollListener) 这三个接口,可以获取抽屉控件的打开,关闭和拉动,同时本类提供了很多方法,详细的大家可以在Android SDK中的android.widget.SlidingDrawer分支查看   2. PopupWindow 气球提示控件   有关PopupWindow可以让我们想起Android刚刚开始有输入法框架的时候,当用户按下屏幕软键盘时,弹出的气球提示,这个View可以用PopupWindow来实现,PopupWindow比较方便的就是可以浮动在一个Activity中,设置成为透明或什么可以当做工具栏来使用。具体的大家可以翻看GIT代码中有关Android输入法的代码了解。   3. […]

Activity类的runOnUiThread方法你用过吗 Android开发技术

  如果你对于Android的Thread+Handler方式感觉繁琐,不妨试试Activity提供的另外一种简单的方法runOnUiThread,runOnUiThread可以帮助你在线程中执行UI更新操作,我们只需要在线程中写上类似      android123.this. runOnUiThread(new Runnable() {                     @Override                         public void run() {                             // refresh ui 的操作代码                         }                     });   这里需要注意的是runOnUiThread是Activity中的方法,在线程中我们需要告诉系统是哪个activity调用,所以前面显示的指明了activity。 

Android平台下图表绘制相关方法 Android开发技术

  很多网友可能会遇到图表绘制等问题,在Android平台下如何我们需要绘制饼图、K线图应该如何处理呢? 在Android平台下绘图的API大多数由Canvas提供类似Win32或Symbian中的DC,提供大量的绘制方法. 对于饼图即PieChart而言,比较简单,首先计算每个区域的百分比,然后通过drawArc方法绘制弧形,方法原型如下:   public void drawArc (RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint) oval  The bounds of oval used to define the shape and size of the arc startAngle  Starting angle (in degrees) where the arc begins sweepAngle  Sweep angle (in degrees) measured clockwise useCenter  If true, include the center […]

Android Theme和Styles内部定义解析 Android开发技术

  昨天我们讲到的有关在AndroidManifest.xml中定义Activity的theme方法来实现无标题的方法,在使用xml让你的Activity无标题方法 一文中讲到的,很多网友不明白为什么这样做,其实在Android123以前的文章中多次提到了styles样式定义方法,今天Android开发网再次把一些网友回顾了解下android样式的内部定义。在一个工程的res/values/theme.xml中我们可以方便的定义自己的风格主题,比如下面的cwjTheme中我们使用了基于android内部的白色调的背景Theme.Light,设置windowsNoTitle为true代表没有标题,背景颜色我们使用了android内部定义的透明,同时设置listView控件的样式为cwjListView,xml样式代码如下:   <?xml version="1.0" encoding="utf-8"?>  <resources>   <style name="cwjTheme" parent="android:Theme.Light">     <item name="android:windowNoTitle">true</item>     <item name="android:windowBackground">@android:color/transparent</item>     <item name="android:listViewStyle">@style/cwjListView</item>   </style>   有关ListView控件我们自定义的风格就是修改下系统listview这个控件的每行分隔符样式,这里我们在工程下res/drawable文件夹下放一个图片名为list_selector图片,这样我们的cwjListView的代码可以这样写   <style name="cwjListView" parent="@android:style/Widget.ListView">       <item name="android:listSelector">@drawable/list_selector</item>     </style>  </resources>   通过定义style可以设置更多,比如让cwjListView的字体颜色就加入textAppearance属性,比如 <item name="textAppearance">@android:style/TextAppearance</item> 等等。

Android Permission列表,ADT 0.9.9 bug Android开发技术

  Android的开发插件ADT 0.9.9升级后遇到了一个低级BUG,就是无法自动列出系统的permission权限列表,这里Android123给出大家如何从SDK查找permission权限的方法,往常我们往androidmanifest.xml文件中添加权限的方法主要是,直接在下图中单击add按钮,会弹出permission列表,如图   但是升级到ADT 0.9.9时,系统无法显示权限对话框,我们添加权限哪里找呢? Android123告诉大家在SDK的reference中,在左边选择 android,然后下方的classes选择manifest.permission即可,这样右边会有显示Summart帮助我们快速查找,如图 有关具体的定义和适用于最低的API Level可以在下面的Constants中找到,如图     最后需要提醒大家的是,直接复制上图的 constant value后面的字符串即可,在androidmanifest.xml中我们是这样写的,比如  <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission> ,不知道Google为什么这样做,给我们开发带来了很多效率上的影响。  本文测试环境为 ADT 0.9.9和SDKr6,不知道SDK Tools r7是否正常,希望网友可以反馈下。

Android数据库ContentProvider封装原理 Android开发技术

   大家都知道Android数据库使用的是SQLite,但是Google为了给我们简化操作,可以不用经常编写容易出错的SQL语句,直接通过ContentProvider来封装数据的query查询、添加insert、删除delete和更新update,我们就以Android系统的SDK中的例子来给大家简单的说明下吧。  public class NotePadProvider extends ContentProvider {     private static final String TAG = "NotePadProvider";     private static final String DATABASE_NAME = "note_pad.db"; //数据库存储文件名,包含了.db后缀    private static final int DATABASE_VERSION = 2; //数据库版本号,这个是自己定义的,未来扩展数据库时自己可以方便的定义升级规则    private static final String NOTES_TABLE_NAME = "notes"; //表名     private static HashMap<String, String> sNotesProjectionMap;  //常规的Notes    private static HashMap<String, String> sLiveFolderProjectionMap; //LiveFoder内容     […]

Android NDK开发技巧一 Android开发技术

  平时我们开发Android应用时可能部分要求由于性能问题需要使用NDK来实现,比如OpenGL、OpenCore这样的多媒体应用,使用本地C/C++语言可以处理一些性能敏感或复杂的算法,Android123就我们日常NDK开发中遇到的问题以及技巧逐一总结方便网友查阅。      1. Android NDK编译的应用可以运行在Android 1.5或更高的操作系统上,在Android平台中本地调用主要通过JNI方式处理,JNI调用开销不小如果很简单的操作没有必要画蛇添足。      2. 一般NDK生成的so文件如何打包到apk中去呢?一般工程目录下创建一个libs文件夹,当然了手动释放也可以比如说 data/data/cn.com.android123.cwj/files/rmvb-decoder.so      3. 在JNI下面,我们常用的命名方式:     static JavaVM *g_VM;   //全局环境指针     static jclass jNativesClass;   (*env)->GetJavaVM(env, &g_VM);   //获取env环境指针,这样以后用g_VM就可以了。      4.   jobjectArray jargv // java数组 int getArrayLen(JNIEnv * env, jobjectArray jarray): //获取一个Java数组长度,返回为jsize类型 jstring jele = (jstring)(*env)->GetObjectArrayElement(env, jargv, n);  //从将Java数组元素n转为本地的jstringconst char *word = (*env)->GetStringUTFChars(env, jele, 0); //将java的utf字符转为c下面的char*    5.  […]

Android JNI开发入门篇 Android开发技术

  昨天我们大概讲了下Android NDK的开发概况和常见的技巧,很多网友感到表示十分感兴趣发来了邮件希望继续,今天Android123还是从头还是谈论下Java的调用C++的JNI,以便大家开发出一些功能较强大些的Android应用,如果有疑问可以仍然来函至 android123@163.com   1. 有关JNI的类型方法表示,很多网友不明白,下面Android开发网就,基本上C层面的类型均是j+java过去的类型,比如字符串在JNI的c层面为jstring而Java为String,对于布尔类型boolean则为jboolean对应Java中的boolean。   2. 有关Java类的表示在JNI中对应关系如下   long cwjInfo (int nAge, String sName, int[] arrSalary);     我们可以表示为  "(ILjava/lang/String;[I)J"    我们去除双引号,第一个(表示一个参数类型,接下来的I表示第一个参数为int整形,L代表是一个类class,这里为java/lang/String这个类,接下来是[代表是一个数组,后面的I代表一个整形的数组,而)后面的J代表返回类型,在JNI中J代表long长整形,相关的对应关系如下: V voidZ booleanB byteC charS shortI intJ longF floatD doubleL fully qualified class[  array type[]( arg-types  3. Java层传入的String不能在JNI中直接转化为jstring,因为Java的内部编码为unicode,中英文的字符都是每个占两个字节,而jni中我们需要使用utf-8来表示,utf-8比较特殊中英文是不等长的,比如英文等符号的ascii占用一个字节,而中文则为三个字节,同时仍然以\n结尾,所以下面这种错误的方法为 JNIEXPORT jstring JNICALL Java_Cwj_ShowLog(JNIEnv *env, jobject obj, jstring log){  printf("%s", log); //这样做是错误的,printf不能直接处理Java传来的类型。   //dosomething 返回jstring等等。} […]

Android JNI开发提高篇 Android开发技术

  有关JNI的开发技术,我们继续围绕Android平台进行,JNI可以支持C或C++,从目前为止我们写过的JNI代码均为C实现的,即文件名为.C而C++的和这些有什么不同呢? Android平台上的JNI一般使用C还是C++编写呢?    Android平台在中间层和大部分的类库的底层使用了C++的开发方式,后缀为.cpp,比如Android Framework、OpenCore、Webkit、SQLite等等。使用C++好处就是可以使用很多库但目前Android不支持STL,我们知道C表示字符串都是字符数组,但C++可以使用类似string这样的类型表示。   1. 代码上编写C和C++有啥区别   这里Android123就以将Java的unicode字符串转为jni中的utf8,然后再返回一个jstring类型为例子,可以看到jni和java之间字符串的转换方法。   C的实现:   JNIEXPORT jstring JNICALL Java_Android123_CwjC (JNIEnv *env, jobject obj, jstring string) {   const char *strUTF = (*env)->GetStringUTFChars(env, string, 0);   char szBuffer[255];   strcpy(szBuffer, strUTF);  (*env)->ReleaseStringUTFChars(env, string, strUTF);  return (*env)->NewStringUTF(env, szBuffer);}  C++的实现:  JNIEXPORT jstring JNICALL Java_Android123_CwjCpp (JNIEnv *env, jobject obj, jstring string){  const char […]

Android JNI开发进阶篇 Android开发技术

       今天Android123主要讲解下昨天需要详细说明有关Java JNI相关的异常处理、线程安全问题,在JNI中产生的异常主要是内存不足OutOfMemoryError、数组越界ArrayIndexOutOfBoundsException、数组赋值类型错误ArrayStoreException以及指针越界等问题。简单的我们昨天在 Android JNI开发提高篇中已经讲到。    除了Throw或ThrowNew来抛出异常外,还提供了5个函数来处理,分别为jthrowable ExceptionOccurred(JNIEnv *env);、void ExceptionDescribe(JNIEnv *env);、void ExceptionClear(JNIEnv *env);  、 jboolean (JNIEnv *env) 和void FatalError(JNIEnv *env, const char *msg);    1. ExceptionCheck 用于检测如果一个异常已经抛出,则该方法将会返回JNI_TRUE就是typedef定义为1的布尔值。    2. ExceptionOccurred 获取正在抛出一个异常的本地引用,Native或Java层必须处理该异常,并返回一个jthrowable对象。    3. ExceptionDescribe主要用于打印出异常的错误描述。    4. ExceptionClear清除刚刚抛出的异常。    5. FatalError 的作用比较特殊,产生一个致命性的错误,Android123提示这样会导致JVM将关闭,就是程序停止运行了,所以使用时要谨慎。   我们以C++的代码做个例子,简单的说明下他们的使用方法    env->FindClass("Android123CWJ"); //假设这个类本身不存在  if(env->ExceptionCheck())  {     env->ExceptionDescribe();     env->ExceptionClear();  }  这样JVM因为查找Android123CWJ类不存在,导致了一个NoClassDefFoundError的异常。   在JNI中处理资源同步问题,JNI提供了一组函数分别为jint MonitorEnter(JNIEnv […]

Android NDK开发技巧二 Android开发技术

  Android NDK相关的开发技巧我们将在今后经常总结,方便网友参考,有关JNI的使用可以查看 Android JNI开发入门篇 、Android JNI开发提高篇、Android JNI开发进阶篇 、Android JNI开发高级篇 和 Android JNI开发终极篇。   Android NDK对于我们的作用和基本常识在 Android NDK开发技巧一 中已经讲明了,今天谈论下实战的技巧吧   1. 在JNI中打印Logcat,首先我们需要在cpp文件中加入 #include <android/log.h> 这个头文件,NDK有关android自己的就给我们这个唯一的文件log.h,其他的需要我们自己hack diy来解决。   jstring jlog;  //从Java传来需要打印的字符  jboolean isCopy;  const char * szLog = (*env)->GetStringUTFChars(env, jlog, &isCopy); //将java的unicode字符转化为utf8字符      __android_log_print(ANDROID_LOG_WARN, “android123-cwj”, "from ndk = %s", szLog); //打印logcat     (*env)->ReleaseStringUTFChars(env, jlog, szLog); // 释放内存} 上面这段比较简单,其中使用__android_log_print函数打印Logcat,第一个参数为log的level,在log.h头文件中定义了 ANDROID_LOG_UNKNOWN = 0、 ANDROID_LOG_DEFAULT,    /* […]

Android JNI开发高级篇 Android开发技术

   有关Android JNI开发中比较强大和有用的功能就是从JNI层创建、构造Java的类或执行Java层的方法获取属性等操作。     一、类的相关操作     1. jclass FindClass(JNIEnv *env, const char *name);  查找类     该函数可能做过Java开发的不会陌生,这个是JNI层的实现,需要注意的是第二个参数为const char*类型的,我们如果从Java从层传入unicode编码的jstring类型需要使用GetStringUTFChars函数转换成utf8的const char*,如果成功返回这个Java类的对象jclass,相关的异常可能有      (1. ClassFormatError 类的数据格式无效     (2. ClassCircularityError 该类或接口是自身的超类或超接口     (3. NoClassDefFoundError 没有找到指定名称的类或接口       (4. OOM内存不足错误,即OutOfMemoryError        2. jclass GetSuperclass(JNIEnv *env, jclass clazz);  获取父类或者说超类         该函数的第二个参数为jclass类,我们调用时传入的是子类,否则返回将是NULL      3. jboolean IsAssignableFrom(JNIEnv *env, jclass clazz1,jclass clazz2);  判断class1对象能否安全的强制转换为class2对象        如果可以将返回 JNI_TRUE,JNI_TRUE的定义值为1,否则返回JNI_FALSE即0 ,这里Android123详细说明下哪些情况可能返回真:      […]

Android JNI实例代码(一) Android开发技术

  前几天Android123有关Android JNI开发系列教程中有关的源代码,可以在本文中查找: 一、 在JNI中执行Java方法 class AndroidJniDemo { private native void executeMethod(); private void show() {  System.out.println("Java cwj print"); //执行了show方法后打印java层的输出 } public static void main(String args[]) {  //这里我们在J2SE中测试,Android开发者可以放到Activity中的onCreate调用  AndroidJniDemo ajd = new AndroidJniDemo();  ajd.executeMethod();  } static {  System.loadLibrary("AndroidJniDemo"); }} 下面是JNI代码: JNIEXPORT void JNICALLJava_AndroidJniDemo_executeMethod(JNIEnv *env, jobject obj){ jclass clazz = (*env)->GetObjectClass(env, obj); //通过类的对象 jmethodID mid = (*env)->GetMethodID(env, clazz, "show", "()V"); //查找java中的show方法的ID,最后的签名符号为void类型 if (mid == NULL) {  return;   //如果方法ID没有找到 }  printf("JNI cwj print"); //从JNI中打印输出 […]

Android JNI实例代码(二) Android开发技术

   我们继续Android JNI开发中的常用代码,第二部分将包含如何在JNI中构造实例化一个Java类以及异常处理的具体方法,有关前一部分的内容可以查看 Android JNI实例代码(一)  。    三、在JNI中构造和实例化Java类  public class AndroidJniDemo4{ public static native void constructClass(); //JNI方法 public static void main(String[] args){  AndroidJniDemo4.constructClass(); }} class CwjThread implements Runnable { int nCount = 0 ; public void run(){  try{   Thread.sleep(1987); //休眠1987毫秒  }catch(Exception e){   e.printStackTrace();  }  System.out.println("Count="+ nCount); }} JNIEXPORT void JNICALLJava_AndroidJniDemo4_constructClass(JNIEnv *env, jclass clazz){ jclass jclazz , cwjclazz;   jmethodID mid , mid2 , runmid ;  jobject obj , obj2 ;  jclazz = […]

Android开发调试工具TraceView多图演示 Android开发技术

  有关Android SDK自带的性能分析调试工具TraceView使用方法,我们在android.os.Debug调试工具使用方法 简单的说过,有关实际使用如下   public void android123_method()   {            android.os.Debug.startMethodTracing("cwj");             //dosomething           android.os.Debug.stopMethodTracing();   }  一般会保存在 /sdcard/cwj.trace 当然2.2或以上可能在/mnt/sdcard/cwj.trace中,同时因为写sdcard需要加入WRITE_EXTERNAL_STORAGE 这个permission ,我们执行adb pull /sdcard/cwj.trace可将文件从sdcard传到pc上,也可以通过ddms的file explorer,等等,执行 traceview cwj或直接从Android SDK中鼠标执行traceview导入cwj.trace文件可以看到如下图   (点击下图 查看原始大图):         我们可以看到每个方法或类型执行的时间百分比,分析Android程序的性能。  

Android开发进阶教程系列(一)目录篇 Android开发技术

  很多开发者反应,目前学习Android开发的资料比较少,很多都是比较简单停留在Activity、Service或Android控件的开发层面,Android123针对网友的问题,将在今后的文章中增加一些中高级内容,帮助Android开发者从入门走向进阶。   在前一段中,我们讲解了有关Android JNI以及NDK开发相关的内容,接下来将会着重说明有关:   1. Java NIO非阻塞包,主要是Socket服务器相关设计。   2. Java Concurrent并发库,对于线程池的处理。   3. Android AIDL服务,编写一个远程服务供多个程序使用。   4. Java反射调用AIDL服务的方法,反射处理Android平台的远程服务。   5. Android高性能2D显示类SurfaceView相关的实例游戏开发教程。   在这期间Android开发网仍然会更新一些适合入门开发者学习遇到的常规问题和注意事项。 国内很多网友的综合能力仍然停留在初级阶段,同时很多出版的书籍比较浅显,很多大同小异无法真正的满足中高级应用的开发需要。您有好的建议可以来函至 android123@163.com 。

Android开发进阶之NIO非阻塞包(一) Android开发技术

  对于Android的网络通讯性能的提高,我们可以使用Java上高性能的NIO (New I/O) 技术进行处理,NIO是从JDK 1.4开始引入的,NIO的N我们可以理解为Noblocking即非阻塞的意思,相对应传统的I/O,比如Socket的accpet()、read()这些方法而言都是阻塞的。   NIO主要使用了Channel和Selector来实现,Java的Selector类似Winsock的Select模式,是一种基于事件驱动的,整个处理方法使用了轮训的状态机,如果你过去开发过Symbian应用的话这种方式有点像活动对象,好处就是单线程更节省系统开销,NIO的好处可以很好的处理并发,对于Android网游开发来说比较关键,对于多点Socket连接而言使用NIO可以大大减少线程使用,降低了线程死锁的概率,毕竟手机游戏有UI线程,音乐线程,网络线程,管理的难度可想而知,同时I/O这种低速设备将影响游戏的体验。   NIO作为一种中高负载的I/O模型,相对于传统的BIO (Blocking I/O)来说有了很大的提高,处理并发不用太多的线程,省去了创建销毁的时间,如果线程过多调度是问题,同时很多线程可能处于空闲状态,大大浪费了CPU时间,同时过多的线程可能是性能大幅下降,一般的解决方案中可能使用线程池来管理调度但这种方法治标不治本。使用NIO可以使并发的效率大大提高。当然NIO和JDK 7中的AIO还存在一些区别,AIO作为一种更新的当然这是对于Java而言,如果你开发过Winsock服务器,那么IOCP这样的I/O完成端口可以解决更高级的负载,当然了今天Android123主要给大家讲解下为什么使用NIO在Android中有哪些用处。    NIO我们分为几个类型分别描述,作为Java的特性之一,我们需要了解一些新的概念,比如ByteBuffer类,Channel,SocketChannel,ServerSocketChannel,Selector和SelectionKey。有关具体的使用,Android开发网将在明天详细讲解。网友可以在Android SDK文档中看下java.nio和java.nio.channels两个包了解。

Android开发进阶之NIO非阻塞包(二) Android开发技术

   有关Android NIO我们主要分为三大类,ByteBuffer、FileChannel和SocketChannel。由于篇幅原因今天Android123只对前两个做说明。NIO和传统的I/O比较大的区别在于传输方式非阻塞,一种基于事件驱动的模式,将会使方法执行完后立即返回,传统I/O主要使用了流Stream的方式,而在New I/O中,使用了字节缓存ByteBuffer来承载数据。    ByteBuffer位于java.nio包中,目前提供了Java基本类型中除Boolean外其他类型的缓冲类型,比如ByteBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer和ShortBuffer  。同时还提供了一种更特殊的映射字节缓冲类型MappedByteBuffer。在传统IO的输入输出流中,InputStream中只提供了字节型或字节数组的访问对应NIO就是ByteBuffer,但是处理传统的DataInputStream的int等类型,就是IntBuffer,但是缓冲类型并没有提供UTF这样的类型处理,所以我们仍然需要使用ByteBuffer处理字符串,但是NIO提供了一个封装的类在java.nio.charset包中,通过字符的编码CharsetEncoder和解码CharsetDecoder类来处理字符串,同时这些类可以方便转换编码比如GBK或UTF等等。   一、ByteBuffer类   1) 实例化   直接使用ByteBuffer类的静态方法static ByteBuffer allocate(int capacity) 或 static ByteBuffer allocateDirect(int capacity)  这两个方法来分配内存空间,两种方法的区别主要是后者更适用于繁复分配的字节数组。而 put(ByteBuffer src) 可以从另一个ByteBuffer中构造,也可以通过wrap方法从byte[]中构造,具体参考下面的类型转化内容。   2) 类型转化    ByteBuffer可以很好的和字节数组byte[]转换类型,通过执行ByteBuffer类的final byte[]  array() 方法就可以将ByteBuffer转为byte[]。从byte[]来构造ByteBuffer可以使用wrap方法,目前Android或者说Java提供了两种重写方法,比如为static ByteBuffer  wrap(byte[] array)  和 static ByteBuffer  wrap(byte[] array, int start, int len)  ,第二个重载方法中第二个参数为从array这个字节数组的起初位置,第三个参数为array这个字节数组的长度。   3) 往ByteBuffer中添加元素   目前ByteBuffer提供了多种put重写类型来添加,比如put(byte b) 、putChar(char value) 、putFloat(float […]

Android开发进阶之NIO非阻塞包(三) Android开发技术

   有关Android NIO的精髓主要用于高负载的Socket网络传输,相对于传统I/O模型的Socket传输方式的优势,我们已经在 Android开发进阶之NIO非阻塞包(一) 中讲到了,这里不再赘述,一起来看看Android NIO有关Socket操作提供的类吧:   一、ServerSocketChannel 服务器套接字通道在Android SDK中查找package名为  java.nio.channels.ServerSocketChannel    在Java的NIO中,ServerSocketChannel对应的是传统IO中的ServerSocket,通过ServerSocketChannel类的socket() 方法可以获得一个传统的ServerSocket对象,同时从ServerSocket对象的getChannel() 方法,可以获得一个ServerSocketChannel()对象,这点说明NIO的ServerSocketChannel和传统IO的ServerSocket是有关联的,实例化ServerSocketChannel 只需要直接调用ServerSocketChannel 类的静态方法open()即可。   二、 SocketChannel 套接字通道 java.nio.channels.SocketChannel      在Java的New I/O中,处理Socket类对应的东西,我们可以看做是SocketChannel,套接字通道关联了一个Socket类,这一点使用SocketChannel类的socket() 方法可以返回一个传统IO的Socket类。SocketChannel()对象在Server中一般通过Socket类的getChannel()方法获得。  三、SelectionKey 选择键 java.nio.channels.SelectionKey   在NIO中SelectionKey和Selector是最关键的地方,SelectionKey类中描述了NIO中比较重要的事件,比如OP_ACCEPT(用于服务器端)、OP_CONNECT(用于客户端)、OP_READ和OP_WRITE。  四、Selector 选择器 java.nio.channels.Selector   在NIO中注册各种事件的方法主要使用Selector来实现的,构造一个Selector对象,使用Selector类的静态方法open()来实例化。   对于Android平台上我们实现一个非阻塞的服务器,过程如下:    1. 通过Selector类的open()静态方法实例化一个Selector对象。    2. 通过ServerSocketChannel类的open()静态方法实例化一个ServerSocketChannel对象。    3. 显示的调用ServerSocketChannel对象的configureBlocking(false);方法,设置为非阻塞模式,Android123提示网友这一步十分重要。    4. 使用ServerSocketChannel对象的socket()方法返回一个ServerSocket对象,使用ServerSocket对象的bind()方法绑定一个IP地址和端口号    5. 调用ServerSocketChannel对象的register方法注册感兴趣的网络事件,很多开发者可能发现Android SDK文档中没有看到register方法,这里Android开发网给大家一个ServerSocketChannel类的继承关系   java.lang.Object    ↳ java.nio.channels.spi.AbstractInterruptibleChannel   […]

Android开发进阶之NIO非阻塞包(四) Android开发技术

   今天我们通过一个实例详细讲解下Android下NIO非阻塞服务器的开发,对于客户端而言Android123不推荐使用NIO,毕竟NIO相对于传统IO较为复杂,最重要的NIO是为了解决多线程并发问题而解决的技术,可能会因为管理和复杂性降低最终的结果,毕竟NIO是Java的,相关的类型比较难控制,对于客户端而言我们可以使用C++、Java、C#甚至Flash Action Script来编写。     下面我们以一个简单的Echo Server为例子来分析  import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.CharBuffer;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.ServerSocketChannel;import java.nio.channels.SocketChannel;import java.nio.charset.Charset;import java.nio.charset.CharsetDecoder;import java.nio.charset.CharsetEncoder;import java.util.Iterator; public class Server {  public static void main(String[] args) {  Selector selector = null;  ServerSocketChannel ssc = null;  try {      selector = Selector.open(); //实例化selector      ssc = ServerSocketChannel.open(); //实例化ServerSocketChannel 对象       ssc.socket().bind(new InetSocketAddress(1987)); //绑定端口为1987       ssc.configureBlocking(false); //设置为非阻塞模式      ssc.register(selector, SelectionKey.OP_ACCEPT); //注册关心的事件,对于Server来说主要是accpet了     while (true) {   […]

Android开发进阶之NIO非阻塞包(五) Android开发技术

  有关Android NIO的注意点和重点今天Android123着重分析下上次 Android开发进阶之NIO非阻塞包(四) 一文中提到的不足地方改进。由于目前国内很多人资料书籍编写人员没有通过NIO实现服务器的经验,导致了很多例子中存在严重的错误,由于大多数例子为Echo这样的单次交互以及数据量较小所以反映不出问题的所在。    1. 读和写应该分开,NIO使用的是异步的方法但不等于说不会阻塞,在上面的例子中我们可以看到 判断  key.isReadable() 时,对于这个SelectionKey关联的SocketChannel尽量不要使用写入数据量过多时ByteBuffer使用hasRemaining这样的方法,NIO每次读写不一定全部要把数据读完在一次Selector时。   2. 对于上面的解决方法我们可以继续关注感兴趣的事件,比如说使用interestOps方法,而很多资料中均使用了错误的继续用Selector的register方法继续注册事件,这样没有发生错误的原因是每次注册时会替换上次的这个key注册的事件,比较侥幸,从效率上讲还会判断这个key上次注册的是什么事件,并不是一种正统的方法。   3. 我们可以继续判断写入事件,比如key.isWritable,在写入时来处理发送数据。这样可以应对很多低速网络时产生的异常。   有关的细节还有很多,下一次Android开发网总结出常见的问题,并给大家一个较科学完善的框架,减少不必要的麻烦产生。

Android 2.3将于12月6日发布 Android开发技术

  近日来自Google官方的消息表示Android 2.3姜饼应该在12月6日发布,同时由三星代工的第二款Google贴牌手机Nexus S也可能同时推出,原先的Nexus One用户也可能是最早收到2.3更新的用户群,这两款机型作为Android开发机型的主推产品在硬件和固件升级速度上均会比HTC、MOTO和Samsung有着更多的优势。   届时Android 2.3 Gingerbread SDK也会在下月的6日同日发布。有关Nexus S的主要配置和三星i9020一样,使用了三星自家的Samsung S5PC100 CPU工作频率为1GHz的A8内核,4英寸Super AMOLED屏、500W摄像头、16GB内存。同时将会预装Android 2.3操作系统。很多网友可能会疑问Nexus S最终和i9020有什么不同,Android123就拿HTC Desire G7和Nexus One作对比吧,G7有HTC Sense UI而N1的界面是Google原生的,没有那么多附属的应用,而本次Nexus S也不会包含三星的TouchWiz主题。   

Android开发进阶之NIO非阻塞包(六) Android开发技术

  有关Android NIO的相关内容,本次Android123整理并归类如下,为了让大家感觉NIO和Android平台联系的紧密,这里我们结合ADT插件的重要开发工具DDMS中的源码进行分析。在android git中的sdk.git文件中,可以找到ddmlib这个文件夹。有关PC和手机的互通内核在这里使用了Java来完全实现。这里Android开发网一起帮助大家了解下PC同步软件的开发原理同时学习下Java中的New I/O技术。    比较重要的代码段我们贴出,逐一分析,其他的网友可以直接预读源码:    AdbHelper.java文件中    public static SocketChannel open(InetSocketAddress adbSockAddr,            Device device, int devicePort) //这是一个重载版本,主要是关联Device实例。            throws IOException, TimeoutException, AdbCommandRejectedException {         SocketChannel adbChan = SocketChannel.open(adbSockAddr); //构造SocketChannel对象,使用常规的open方法创建        try {            adbChan.socket().setTcpNoDelay(true); //设置TCP非延迟            adbChan.configureBlocking(false); //非阻塞             setDevice(adbChan, device); //本句和NIO没有多大关系,这句是指定具体的设备,比如模拟器,或Android手机的厂家代号,比如宏达电的以HTXXXXX这样的方式             byte[] req = createAdbForwardRequest(null, devicePort); //设置端口转发,这句很关键,否则PC和手机通过USB是无法互通的。            write(adbChan, req); //发送数据             AdbResponse resp = […]

Android开发进阶之NIO非阻塞包(七) Android开发技术

  今天我们继续就Android DDMS源码一起分析NIO非阻塞通讯方式,Android123也会给大家分享下手机和PC互通中的一些技术。在NIO中有关SocketChannel和ByteBuffer的使用细节,可以在今天文章中    static void read(SocketChannel chan, byte[] data, int length, int timeout)            throws TimeoutException, IOException {        ByteBuffer buf = ByteBuffer.wrap(data, 0, length != -1 ? length : data.length); //从字节数组中实例化ByteBuffer        int numWaits = 0;         while (buf.position() != buf.limit()) {  //循环接收数据            int count;             count = chan.read(buf);            if (count < 0) {                    throw […]

Android开发进阶之NIO非阻塞包(八) Android开发技术

   在整个DDMS中体现Android NIO主要框架的要数MonitorThread.java这个文件了,有关PC和Android手机同步以及NIO非阻塞编程的精髓可以在下面的文件中充分体现出来。   final class MonitorThread extends Thread {     private static final int CLIENT_READY = 2;     private static final int CLIENT_DISCONNECTED = 3;     private volatile boolean mQuit = false;     private ArrayList<Client> mClientList; //用一个数组保存客户端信息     private Selector mSelector;     private HashMap<Integer, ChunkHandler> mHandlerMap; //这里Android123提示大家,由于在多线程中concurrentHashMap效率比HashMap更安全高效,推荐使用并发库的这个替代版本。     private ServerSocketChannel mDebugSelectedChan; //一个用于调试的服务器通道     private […]

Android控件对应表,丰富你的UI设计 Android开发技术

  在Android平台上提供给大家很多丰富的控件,设计一个漂亮的UI在Android平台下可以说是最简单的事情了。   ListView – 列表控件,系统中的通话记录每一条就是使用这个控件编写的。   GridView – 网格控件,我们常见的n宫格设计就是出自这个控件。   TabHost和TabWidget – 这两个组合可以实现标签页的显示效果,类似IE7的一个窗口可以切换多个页面。   ExpandableListView – 这个其实就是TreeView控件,可以实现树状图显示,对于分级显示的内容很方便。   ImageSwitcher 和 Gallery – 图片浏览控件,可以很容易实现类似iPhone上面的Coverflow效果,Android平台自带的控件还是很人性化的。   AnalogClock – 经典桌面Widget的两根针钟表控件,换两个指针以及表盘就可以实现自己的钟表,很轻松哦。   VideoView – 目前绝大多数的Android视频播放器都是使用了VideoView如果有的网友说我使用的是SurfaceView呢? Android开发网明确告诉你吧,你的代码可能就是从开源的VideoView中改造而来的,只不过自定义了一个名称这么简单,所以说Android的应用层开发更像搭积木。   有关运行的效果,Android123建议大家运行SDK目录下的ApiDemo在模拟器和真机上更好的体验,静态图片无法演示出控件实际的运行效果。

更轻松的获取APK文件安装时间 Android开发技术

   很多Android开发者想设计一个APK管理程序,获取APK文件的安装日期很多网友不是很明白。在早期Android123使用的方法是通过PackageManager类的getInstalledApplications方法返回一个ApplicationInfo数组,ApplicationInfo类中sourceDir可以获取APK的文件路径,从而使用File类读取文件的上次修改时间而实现。但这可能导致:   1. 无法获取原始的创建时间,可能很早就被创建了,之后被替换了。   2. 如果这个APK在一个私有的位置,比如app-private目录,使用Market付费购买的应用在这个位置,如果没有Root的Android手机是没有权限读取的,也导致获取时间失败。   在Android 2.3 API Level为9中,ApplicationInfo类新增的firstInstallTime和lastUpdateTime这两个字段,可以直接获取到APK的创建或上次修改的时间,即使是付费软件也能正常的获取。

Android 2.3中的java.io.File类新增功能 Android开发技术

  对于Android 2.3来说原始Sun公司的java.io.File包中的内容也有了改进,File类在API Level为9时多出了很多新特性,比较实用的有:   public long getFreeSpace ()  返回这个分区包含这个路径的剩余空间,如果返回0则表示不存在,下面为SDK原文    Returns the number of free bytes on the partition containing this path. Returns 0 if this path does not exist. Note that this is likely to be an optimistic over-estimate and should not be taken as a guarantee your application can actually write this […]

Android平台上的11个感应器你都知道吗 Android开发技术

   在Android 2.3中新增了3个感应器,对于Android平台的开发我们通过感应器可以发挥想象设计出一些很实用的软件。下面就一起看下目前API Level为9时一共11个感应器分辨是什么吧.   1. ACCELEROMETER 加速,描述加速度的。   2.GRAVITY 重力,这个在大家都知道。   3.GYROSCOPE 陀螺仪,对于物体跌落检测更强大些,开发游戏少了它会有点遗憾的,API Level 9新增的类型。   4. LIGHT 光线感应器,很多Android手机的屏幕亮度是根据这个感应器的数组自动调节的。   5. LINEAR_ACCELERATION 线性加速器,API Level 9新增的。  6. MAGNETIC_FIELD 磁极感应器。   7. ORIENTATION 方向感应器。   8. PRESSURE 压力感应器。    9. PROXIMITY 距离感应器,对于通话后关闭屏幕背光很有用。   10. ROTATION_VECTOR 旋转向量,Android 2.3新增的,如果我们过去处理图像会发现这个还是很有用的,不过这里还是对游戏开发起到辅助。  11. TEMPERATURE 温度感应器,可以获取手机的内部温度,不过和周边的有些差距,毕竟手机内部一般温度比较高。    对于以上感应器Android123提醒开发者,除了特别描述API Level为9或2.3之外的,SDK在1.5即Level 3时就已经支持了,不过最终使用还要看手机硬件的支持,很多山寨机或小品牌的设备可能会在这些上面偷工减料,同时Android开发网提醒大家,感应器的数据刷新比较快一般,考虑到电池功耗一般长时间使用CPU的占用率可能会提升,影响系统性能。   列举手机上已经有的感应器,可以通过SensorManager类的List<Sensor>  getSensorList(int type)  […]

DownloadManager下载管理类2.3新增API介绍 Android开发技术

  从Android 2.3开始新增了一个下载管理类,在SDK的文档中我们查找android.app.DownloadManager可以看到。下载管理类可以长期处理多个HTTP下载任务,客户端只需要给出请求的Uri和存放目标文件的位置即可,下载管理使用了一个AIDL服务器所以可以放心的在后台执行,同时实例化的方法需要使用getSystemService(Context.DOWNLOAD_SERVICE) ,Android123再次提醒使用API Level为9的用户可以轻松的通过新增的这个API实现Android平台上的文件下载操作。  DownloadManager类提供了以下几种方法来处理,   long  enqueue(DownloadManager.Request request)   //存入队列一个新的下载项  ParcelFileDescriptor  openDownloadedFile(long id)  //打开一个下载后的文件用于读取,参数中的long型id是一个provider中的一条记录。 Cursor  query(DownloadManager.Query query)  //查询一个下载,返回一个Cursor int  remove(long… ids)  //取消下载同时移除这些条从下载管理中。   我们可以看到提供的方法都比较简单,给我们操作的最终封装成为一个provider数据库的方式进行添加、查询和移除,但是对于查询和添加任务的细节,我们要看看DownloadManager.Request类和DownloadManager.Query 类了。   一、DownloadManager.Request类的成员和定义 DownloadManager.Request  addRequestHeader(String header, String value)  // 添加一个Http请求报头,对于这两个参数,Android开发网给大家举个小例子,比如说User-Agent值可以为Android123或Windows XP等等了,主要是给服务器提供标识。DownloadManager.Request  setAllowedNetworkTypes(int flags)  //设置允许使用的网络类型,这一步Android 2.3做的很好,目前有两种定义分别为NETWORK_MOBILE和NETWORK_WIFI我们可以选择使用移动网络或Wifi方式来下载。DownloadManager.Request  setAllowedOverRoaming(boolean allowed)  //对于下载,考虑到流量费用,这里是否允许使用漫游。DownloadManager.Request  setDescription(CharSequence description)  //设置一个描述信息,主要是最终显示的notification提示,可以随便写个自己区别DownloadManager.Request  setDestinationInExternalFilesDir(Context context, String dirType, String subPath)  //设置目标存储在外部目录,一般位置可以用 getExternalFilesDir()方法获取。DownloadManager.Request  setDestinationInExternalPublicDir(String dirType, […]

100% Secure Checkout

PayPal / MasterCard / Visa