android重要知识点


WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang 高手整理的android重要知识点 【提示:请尽量使用 Adobe reader 阅读本文档】 下载更多相关源代码、电子书、工具包请访问:http://share.cnmsdn.com/ 我分享的更多移动开发资源:http://share.cnmsdn.com/user/wzfyang 我们都知道App维护者一个startActivity可能会使用Launcher,所以考虑单任务的实现方法比较简单,首先androidmanifest.xml的 android:launchMode="singleInstance"这句,其实这样将不会起到任何作用,Activity,我们必须在android:launchMode="singleInstance" 这句才能保证单实例,当然一般均加在主程序启动窗口的 dip设备独立像素px像素转为Android的设备分辨率众多,目前主流的为hvga甚至低端的dip无非是比较方便的,由于他和分辨率无关和屏幕的密度大小有关,所以推荐使用。 android开发网提示大家很多网友获取)的方法存在问题,从资源中获取的是静态定义的,一般为HVGA是正好的,而对于WindowsManager中获取,1.5 这里可以再补充一下sip的知识3. Android中动态改变 很多网友可能发现在ImageView的绝对大小后,无法动态修改以后的大小显示,其实UI控件时考虑到这个问题,为了适应不同的xml的相关android:scaleType="fitXY" 这行即可,但因为使用了缩放可能会造成当前ImageView所在的层,可以使用一个内嵌的方法限制显示。4. 如何判断? 如果拟开发一个网络应用的程序,首先考虑是否接入网络,在 ConnectivityManager 类的 ConnectivityManager cwjManager=(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); ,使用True则表示当前WiFi或HSDPA 等等,具体的可以通过getActiveNetworkInfo() 方法判断详细的接入方式,需要注意的是有关调用需要加入android开发网提醒大家在真机上Browser 程序都使用了这个方法,来判断是否继续,同时在一些网络超时的时候也可以检查下网络连接是否存在,以免浪费手机上的电力资源。5. Drawable、Canvas和 很多网友刚刚开始学习Drawable、Canvas和Drawable外早在J2ME中就已经出现了,但是在Bitmap、 Android平台中的显示类是android.graphics,今天所说的这些均为 bmp,当然编码器也有很多如RGB888。作为一种逐像素的显示对象执行效率高,但是缺点也很明显存储效率低。我们理解为一种存储对象比较好。 Drawable - 作为GIF、JPG,当然也支持 1 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang Bitmap、Path路径,同时它可以配合Canvas类还提供了裁剪、选取等操作。 Paint - 我们可以把它看做一个画图工具,比如画笔、画刷。他管理了每个画图工具的字体、颜色、样式。 如果涉及一些 onCreate重复执行Activity在切换到后台或布局从横屏PORTRAIT,会重新切换onCreate方法,我们可以在activit元素加入这个属性 android:configChanges="orientation|keyboardHidden" 同时在Java文件中重载onCreate等方法。代码如下@Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { //land } else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { //port } } ImageButton问题Android提供的Drawable 图片时就不会再显示文字了,其实解决的方法有两种,第一种就是图片中就写入文字,但是这样解决会增加程序体积,同时硬编码方式会影响多国语言的发布。第二种解决方法很简单,通过分析 可以看到layout,我们可以直接直接继承,添加一个ImageButton支持文字右侧显示。8. Android代码优化技术1.Java内存控制 对于字符串操作而言如果需要连加这样的操作建议使用String需要的内存开销会远大于Android手机常规的运行内存大约在Android 开发网提示因为GC不需要手动释放那么分配的时候就要格外的小心,频繁的logcat查看内存释放情况。 2.循环使用 平时在访问一个属性的时候效率远比一个固定变量低,如果你的循环估计次数常常大于xxx.GetLength()方法的值一般大于 这里 for(int i=0;i 有关listview这个控件的每行分隔符样式,这里我们在工程下list_selector图片,这样我们的 通过定义cwjListView的字体颜色就加入 @android:style/TextAppearance 等等。11.Android JSON解析示例代码Google官方的有关JSON解析示例,如果远程服务器使用了xml的数据提供,在org.json包可以很方便的实现手机客户端的解析处理。下面Android 开发者需要有关JSON解析、 AppWidgetProvider ANR,所以 } ComponentName thisWidget = new ComponentName(this, WordWidget.class); AppWidgetManager manager = AppWidgetManager.getInstance(this); manager.updateAppWidget(thisWidget, updateViews); } Time today = new Time(); today.setToNow(); try { SimpleWikiHelper.prepareUserAgent(context); pageContent = SimpleWikiHelper.getPageContent(pageName, false); } catch (ApiException e) { Log.e("WordWidget", "Couldn't contact API", e); 3 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang } catch (ParseException e) { Log.e("WordWidget", "Couldn't parse API response", e); } SimpleWikiHelper类 String wordTitle = matcher.group(1); updateViews.setTextViewText(R.id.word_title, wordTitle); updateViews.setTextViewText(R.id.word_type, matcher.group(2)); updateViews.setTextViewText(R.id.definition, matcher.group(3).trim()); Uri是url,view即打开 PendingIntent pendingIntent = PendingIntent.getActivity(context, 0 /* no requestCode */, defineIntent, 0 /* no flags */); updateViews.setOnClickPendingIntent(R.id.widget, pendingIntent); // 单击Activity @Override public IBinder onBind(Intent intent) { // We don't need to bind to this service return null; } } } : public static final String WORD_OF_DAY_REGEX = "(?s)\\{\\{wotd\\|(.+?)\\|(.+?)\\|([^#\\|]+).*?\\}\\}"; http://en.wiktionary.org/w/api.php?action=query&prop=revisions&titles=%s private static final String WIKTIONARY_EXPAND_TEMPLATES = "&rvexpandtemplates=true"; private static byte[] sBuffer = new byte[512]; public static class ApiException extends Exception { public ApiException(String detailMessage, Throwable throwable) { super(detailMessage, throwable); } 4 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang public static class ParseException extends Exception { public ParseException(String detailMessage, Throwable throwable) { super(detailMessage, throwable); } } } catch(NameNotFoundException e) { Log.e(TAG, "Couldn't find package information in PackageManager", e); } } String content = getUrlContent(String.format(WIKTIONARY_PAGE, encodedTitle, expandClause)); try { JSONObject response = new JSONObject(content); JSONObject query = response.getJSONObject("query"); JSONObject pages = query.getJSONObject("pages"); JSONObject page = pages.getJSONObject((String) pages.keys().next()); JSONArray revisions = page.getJSONArray("revisions"); JSONObject revision = revisions.getJSONObject(0); return revision.getString("*"); } catch (JSONException e) { throw new ParseException("Problem parsing API response", e); } } HttpClient client = new DefaultHttpClient(); HttpGet request = new HttpGet(url); request.setHeader("User-Agent", sUserAgent); // 设置客户端标识 try { HttpResponse response = client.execute(request); HttpEntity entity = response.getEntity(); InputStream inputStream = entity.getContent(); // 获取 int readBytes = 0; while ((readBytes = inputStream.read(sBuffer)) != -1) { content.write(sBuffer, 0, readBytes); // 转化为字节数组流 return new String(content.toByteArray()); //从字节数组构建widget例子比较简单,主要是帮助大家积累常用代码,了解 JSON的处理方式,毕竟很多Java的。12.Android中使用定时器 在Java上自带的TimerTask相对于Android自带的Timer定时器是一种更好的解决方法。import java.util.Timer; 和private Timer mTimer = new Timer(true); private TimerTask mTimerTask; 5 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang 1秒后每log.v打印输出。 如果想取消可以调用下面方法,取消定时器的执行 while(!mTimerTask.cancel()); mTimer.cancel(); Android123提示大家,如果处理的东西比较耗时还是开个线程比较好,Handler的 Icon大小在不同分辨率下定义Android平台来说,不同分辨率下HDPI即hdpi的应用72x72,而标准的hvga为HTC和QVGA的使用了32x32,常见的: android界面设计的安全色,如下表 png的透明格式,直接鼠标右键另存为即可 sdk文档上的关于界面图标的详细说明。14.Android控件美化? 如果你对UI控件感觉不够满意,可以尝试下自定义控件,我们就以Android123就写到过xml的drawable这样的图片外今天shape的方法,对于Android上支持以下几种属性 gradient、corners等。 我们就以目前系统的selector为例说下 shape的定义,分别为渐变,在startColor属性为开始的颜色,angle是角度。接下来是corners为拐角这里padding。Button完整的定义可以为 注意item的区别主要是体现在state_focused获得焦点时,当当来判断显示什么类型,而没有item可以看作是常规状态下。15. Android开发者应该保持以下特质Android123 推荐新手应该遵循 1. 深读 7 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang SDK的Samples GIT开源代码 4. 多了解 Sun原生的Comparator接口实现Comparable接口的ArrayList可以通过这两个接口进行排序和比较,这里 private final Collator collator = Collator.getInstance(); public final int compare(Object a, Object b) { CharSequence a = ((Item) a).sName; CharSequence b = ((Item) b).sID; return collator.compare(a, b); } }; 我们的mList,则执行排序可以调用方法Collections.sort(mList, cwjComparator); TextProgressBar进度条上显文字Android系统的进度条控件默认的设计的不是很周全,比如没有包含文字的显示,那么如何在? 来自addView这样的方法通过覆盖一层 boolean mChronometerFollow = false; int mChronometerGravity = Gravity.NO_GRAVITY; public TextProgressBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public TextProgressBar(Context context) { super(context); } @android.view.RemotableViewMethod 8 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang public void setDurationBase(long durationBase) { mDurationBase = durationBase; if (mProgressBar == null || mChronometer == null) { throw new RuntimeException("Expecting child ProgressBar with id " + "'android.R.id.progress' and Chronometer id 'android.R.id.text1'"); } // Update the ProgressBar maximum relative to Chronometer base mDuration = (int) (durationBase - mChronometer.getBase()); if (mDuration <= 0) { mDuration = 1; } mProgressBar.setMax(mDuration); } public void onChronometerTick(Chronometer chronometer) { if (mProgressBar == null) { throw new RuntimeException( "Expecting child ProgressBar with id 'android.R.id.progress'"); } // Stop Chronometer if we're past duration long now = SystemClock.elapsedRealtime(); if (now >= mDurationBase) { mChronometer.stop(); } 18. Android内存管理 很多时候我们需要考虑Dalvik VM给每个进程都分配了一定量的可用堆内存,当我们处理一些耗费资源的操作时可能会产生(OutOfMemoryError)这样的异常,Market 客户端设计,基本上都没有采用很好的内存管理机制和缓存处理。 如果细心的网友可能发现50个,再往回滚动时可能我们看到了部分SQLite 数据库中缓存的,但是在内存中已经通过类似 Java中内存管理,引用分为四大类,强引用WeakReference、软引用PhantomReference。它们的区别也很明显,OOM也不会导致这一引用的对象被回收,而Android Market中每个应用的SoftReference来解决内存不至于快速回收,同时当内存短缺面临OOM前时,软引用将会强制回收内存,最后的虚引用一般没有实际意义,仅仅观察 ReferenceQueue一起使用。 对于一组数据,我们可以通过SoftReference 对象来临时保留一些数据,同时对于需要反复通过网络获取的不经常改变的内容,可以通过本地的文件系统或数据库来存储缓存,希望给国内做 Android开发中的利弊Android 2.2的推出,很多新的Java的反射机制JDK中声明好的方法直接调用JVM的,从 ? Android的internal或AIDL接口均可以通过反射轻松调用。 2. 反射对于Android 1.5到API Level从8可以方便的扩充,调用前我们预留一个标志位声明该API Level为多少可以调用。 3. 对于调试Logcat中我们可以看到出错的地方肯定有类似Android应用程序。 反射的缺点有哪些 1. 因为是动态执行的,效率自然没有预编译时引用现有的库效率高,就像平时我们h文件,直接通过20%,对于一些复杂的涉及 9 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang Dalvik崩溃出3个异常捕获,本身Android开发我们必须考虑这些问题。 3. 反射因为导致代码臃肿,自然稍微复杂的几个方法实用反射将会导致代码可读性和维护性降低,如果很抽象的调用 Reflection并不是.Net也同样支持,同时更多的动态语言如 Thread加Android平台很多应用使用的都是Thread和UI,这里Android 1.5开始系统将android.os包中,过去在很早1.0 SDK时其实官方将其命名为JDK 1.5 开始新增的J2EE的网友可能明白并发库效率和强大性,比Thread更灵活和强大,但对于轻量级的使用更为占用系统资源。Java早期为实现多线程而设计的,比较简单不支持Android UI的刷新Handler和 AsyncTask代替Google在I/O操作,比如下载文件、读写数据库等等,它们在本质上都离不开消息,但是Thread加AsyncTask缺点也是有的比如一旦线程开启即Thread和 Looper可能更灵活。21. Android Drawable叠加处理方法Bitmap的叠加处理在Canvas一层一层的画就行了,而? 除了使用getBitmap方法将Bitmap外,今天 LayerDrawable类,: array[0] = new PaintDrawable(Color.BLACK); // 黑色 array[2] = new BitmapDrawable(bm); // 位图资源Drawable数组1代表数组的第二个元素,为白色2代表数组的第三个元素,为位图资源 上面的方法中Android开发网提示public void setLayerInset (int index, int l, int t, int r, int b) 其中第一个参数为层的索引号,后面的四个参数分别为top、 bottom。对于简单的图片合成我们可以将第一和第二层的BitmapDrawable即可实现简单的图片合成。22. onRetainNonConfigurationInstance和Android 横竖屏切换时会触发onRestoreInstanceState,但是Activity类还有一个方法名为getLastNonConfigurationInstance这两个方法。 我们可以通过 onSaveInstanceState,比如距离 @Override public Object onRetainNonConfigurationInstance() { // 这里需要保存的内容,在切换时不是Object来代替 onRestoreInstanceState,而代替的是onCreate中使用,比如 Object obj = getLastNonConfigurationInstance(); 最终 Android123提醒大家,每次onCreate方法都会被触发。23. Android中format方法Google在设计MVC 架构方式,可以让写公共代码、美工和具体逻辑开发人员独立出来。有关values/strings.xml中如何实现格式化字符串呢Android123 举个简单的例子,以及最终可能会用到哪些地方。 cwj_Demo android 开发网 Delete xxx File ? 的时候,我们可能需要在 xxx 的名称,所以定义资源时使用格式化可以轻松解决,不需要一堆 StringBuffer一个一个 %1$s代表这是一个字符串型的,如果是整数型可以写为printf这样的格式化字符串函数,当然如果包含了多个需要格式化的内容,则第二个可以写为%2$d了,那么最终在? 看下面的例子 例一 secret这样的%1$d不是 10 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang String sAgeFormat = getResources().getString(R.string.alert); 这样执行完后,就组成了. 当然了,下面看下. : 字符串型的 String sName="cwj" 资源定义为 则 String sFinalInfo=String.format(sInfoFormat, sName, sCity); MFC的Mac OS中的C#中那样显示的标出参数的数字,比如%n,这里数字代表参数的第sFinalInfo显示的内容为 My name is cwj , I am form Shanghai 。当然了你有什么不懂的地方可以来函至android123@163.com24. Android工程内嵌资源文件的两种方法Android软件一般处理大的资源通过sdcard,而: cwj.dat一个二进制文件,我们可以读取可以直接 方法二 工程根目录下的assets/cwj.dat 这样我们使用下面的代码 AssetManager am = context.getAssets(); InputStream is = am.open(cwj.dat); Android123提示大家Android系统处理bug,在1MB的文件,不然会报异常具体数值大家可以测试下传个稍大的文件,我们在两年前的文章中有提到,而第一种4MB的 View以及 对于View可能大家都熟悉了,对于自定义Android的Android123一起再带大家温习一下 CwjView myView=new CwjView(context); onCreate中Layout的 当然,我们也可以直接从父类声明比如 11 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang 上面我们仅用了父类android命名空间,而名称为layout_height,我们自定义的控件可能有更多的功能,比如 12 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang android:windowBackground即背景值为android123图片为背景,更多的属性定义可以参考layout xml属性设置,比如我们设置所有字体颜色、大体大小和样式,可以在 android123的图片改进下,使用一个bitmap对象,则 bitmap对象来解析android:tileMode是tileMode设置为bitmap资源,比如我们的背景是一层楼,那么全屏可以显示同样的为 bitmap的属性repeat外还有其他的值比如mirror,这些值并没有在Android开发网的Android自定义layout属性全攻略bitmap属于android框架,所以下载base 包,找到该类,类的实例化时 View以及 说的很清楚,所以我们定位到attr.xml有关bitmap的更多属性如filter和 monkey压力测试实战Android开发者可能因为没有充分测试自己的软件造成很容易出现Android固件中自带的monkey工具可以模拟各种按键,触屏,轨迹球、Android123 提示大家说白了android软件,看看会不会产生异常。 具体的使用我们通过adb调试桥链接设备或模拟器,进入adb shell获取设备的adb命令执行,比如说monkey 工具中的参数说明,如图 我们要测试的android设备中已经安装,当然模拟器中也可以测试的。执行p参数,这里代表已安装软件的v代表查看100为我们测试的随机事件数量为 View 有关View的框架今天我们一起讨论下,对于常规的游戏,我们在: 1.控制事件View 3. 绘制 1. 对于控制事件今天我们只处理按键事件onTouchEvent以及 view的方法这里主要有view刷新 invalidate(Rect dirty) ,刷新一个特性 invalidateDrawable(Drawable drawable) ,执行view为无效,最终导致view 比较简单,handler方式外,可以在postInvalidate方法来实现。 3. 绘制onDraw()中通过形参drawRect、drawPath等等。view的位置和大小,比如 onLayout(boolean, int, int, int, int) Called when this view should assign a size and position to all of its children 和Logcat获取当 cwjView是我们为今后游戏设计的一个简单自定义Android平台自定义Java支持多继承可以帮助我们不断的完善复杂的问题。public class cwjView extends View { setFocusableInTouchMode(true); // 获取焦点时允许触控 @Override protected Parcelable onSaveInstanceState() { // 处理窗口保存事件 Bundle bundle = (Bundle) state; { 13 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang super.onSizeChanged(w, h, oldw, oldh); } setMeasuredDimension } @Override protected void onLayout (boolean changed, int left, int top, int right, int bottom) { super.onLayout (changed,left,top, ight,bottom) ; } view的左上角四分之一填充为红色 @Override public boolean onTouchEvent(MotionEvent event) { return super.onTouchEvent(event); // 让父类处理屏幕触控事件 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // 处理按键事件,响应的轨迹球事件为 break; default: return super.onKeyDown(keyCode, event); } return true; } 上面我们可以看到View的大小,可以尝试下面的方法 @Override protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) { height = View.MeasureSpec.getSize(heightMeasureSpec); width = View.MeasureSpec.getSize(widthMeasureSpec); setMeasuredDimension(width,height); // 这里面是原始的大小,需要重新计算可以修改本行 //dosomething 29. Canvas和 昨天我们在 View详解中提到了Android的Paint对象的使用实例。 Canvas类主要实现了屏幕的绘制过程,其中包含了很多实用的方法,比如绘制一条路径、区域、贴图、画点、画线、渲染文本,下面是Android 开发网提示大家很多方法有不同的重载版本,参数更灵活。 void drawRect(RectF rect, Paint paint) // 绘制区域,参数一为 Path路径对象 void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) //贴图,参数一就是我们常规的(Android123提示这里是(应该在),参数四是Rect不等于目标 x轴位置,参数二起始点的x轴水平位置,参数四Paint画刷对象。 void drawPoint(float x, float y, Paint paint) // 画点,参数一水平y轴,第三个参数为 void drawText(String text, float x, float y, Paint paint) // 渲染文本,String类型的文本,参数二y轴,参数四是 14 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang Path路径对象 从上面来看我们可以看出Paint对象。如果我们把Paint就是我们绘画的工具,比如画笔、画刷、颜料等等。 Paint 类常用方法void setARGB(int a, int r, int g, int b) 设置alpha透明通道alpha不透明度,范围为void setAntiAlias(boolean aa) // 是否抗锯齿void setColor(int color) //设置颜色,这里Color类包含了一些常见颜色定义 void setLinearText(boolean linearText) // 设置线性文本 Rasterizer setRasterizer(Rasterizer rasterizer) // 设置光栅化 void setTextScaleX(float scaleX) // 设置文本缩放倍数, void setTextSize(float textSize) // 设置字体大小Typeface包含了字体的类型,粗细,还有倾斜、颜色等。void setUnderlineText(boolean underlineText) // 设置下划线Canvas和onDraw中直接使用@Override protected void onDraw(Canvas canvas) { paintRed.setColor(Color.Red); 11,3上画一个红点 下一次Path路径,和字体 在View和Android123从Android图形显示基类的相关方法和注意点。 自定义: View中所有的子控件均被映射成 View分配所有的子元素的大小和位置时触发onSizeChanged(int, int, int, int) 当 15 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang View获取或失去焦点时触发onWindowFocusChanged(boolean) 当窗口包含的 view被附着到一个窗口时触发onDetachedFromWindow() 当Android123提示该方法和 view发生变化时触发 以上是onDraw(Canvas)用的的是最多的: @Override protected void onDraw(Canvas canvas) { // 这里我们直接使用Paint来选择要填充的颜色 Paint paintBackground = new Paint(); paintBackground.setColor(getResources().getColor(R.color.xxx)); // 从xxx的 canvas.drawRect(0, 0, getWidth(), getHeight(), paintBackground); //设置当前画布的背景颜色为0,0作为为起点,以当前画布的宽度和高度为重点即整块画布来填充。 具体的请查看Canvas和Canvas 中我们可以实现画路径,图形,区域,线。而 (一般用于横竖屏切换Activity中可以调用外,开发游戏时我们尽量在 x和 super.onRestoreInstanceState(bundle.getParcelable("android123_state")); return; } View中如果需要强制调用绘制方法invalidate()方法,它有很多重载版本,同时在线程中的Android游戏开发之旅六中的View完整篇讲到。31. View和Android游戏当中充当主要的除了控制类外就是显示类,在Display和Google Android中涉及到显示的为Android游戏开发中比较重要和复杂的就是显示和游戏逻辑的处理。这里我们说下android.view.SurfaceView。View 基类中派生出来的显示类,直接子类有VideoView,可以看出Camera摄像头一般均使用? SurfaceView可以控制表面的格式,比如大小,显示在屏幕中的位置,最关键是的提供了getHolder方法获取,相关的有void removeCallback(SurfaceHolder.Callback callback)、SurfaceHolder.Callback 接口回调中可以通过下面三个抽象类可以自己定义具体的实现,比如第一个更改格式和显示画面。abstract void surfaceChanged(SurfaceHolder holder, int format, int width, int height) abstract void surfaceCreated(SurfaceHolder holder) abstract void surfaceDestroyed(SurfaceHolder holder) 对于Android底层还提供了SurfaceView而不是直接从Android123未来后面说到的GLSurfaceView也是从该类实现。32. Android程序内存管理必读J2ME或Android开发网本次给大家一些架构上的指导,防止出现豆腐渣工程的出现。Java 语言为主的智能平台对于我们开发一些高性能和质量的软件来说了解 Android的Sun JVM没有什么大的区别仅仅是字节码的优化,我们要知道什么时候用recycle以及到底用不用Java对内存的分配只需要 Java的四种引用方式,比如强引用,软引用,弱引用以及虚引用。一些复杂些的程序在长期运行很可能出现类似 16 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang gc,不用的对象可以显示的设置为空,比如Android123提示大家,gc 使用的是一个有向图,判断一个对象是否有效看的是其他的对象能到达这个对象的顶点,有向图的相对于链表、二叉树来说开销是可想而知。3.Android为每个程序分配的对内存可以通过 totalMemory() freeMemory() 两个方法获取heap内存获取,可以通过getMinimumHeapSize() 方法获取最小可用堆内存,同时显示释放软引用可以调用该类的 concurrent类的线程池解决线程创建的效率瓶颈。5. 不要在循环中创建过多的本地变量。Android和Android123将在以后的文章中详细讲述如何调试Android上的 在TextView的TrueTypeFont的字体文件即Win32系统的用户可以直接在Android的1MB体积的限制,我们先找个英文字体做测试。这里我们将字体文件assets文件夹的 tv.setTypeface(tf); // 设置 tv.setText("CWJ Test"); tv.setTextSize(12); tv.setTextColor(Color.RED); ListView的选择项 int curPos = listView.getFirstVisiblePosition(); 当然是用 ,设置当前选择位置AbsListView为基类的 很多网友可能直接将自己的Android平台,其实android.text.format这个包中,它提供了强大的标准化解析方法: 1. IP地址解析类android.text.format.Formatter中提供了socket中的127.0.0.1的Linux平台的字节顺序,即小字节序、低字节序 细心的网友可能还看到了formatFileSize方法,该方法long型,一般为 12KB、20MB的字符串。 3. 日期时间解析类android.text.format.DateFormat这个Java中的三种时间对象,: Date对象final static CharSequence format(CharSequence inFormat, Calendar inDate) //Calendar 对象final static CharSequence format(CharSequence inFormat, long inTimeInMillis) //long对象 我们可能看到了第一个参数均为CharSequence接口的Android开发网提示大家注意大小写要区分,如 April 6, 1970 at 3:23am 例子,那么Android123的 对于判断一个时间是否为android.text.format.DateFormat类的 17 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang 目前来说JIT性能有了本质的提高,不过对于老版本的程序提高Android123提到的不是语法糖,而是基础的问题,对于SDK: 上面的静态类zero、two来做对比。 int sum = 0; for (int i = 0; i < mArray.length; ++i) { sum += mArray[i].mSplat; } } public void one() { // 通过本地对象改进性能Java 1.5的新语法特性可以大幅改进性能zero() is faster. It pulls everything out into local variables, avoiding the lookups. Only the array length offers a performance benefit. is fastest for devices without a JIT, and indistinguishable from for devices with a JIT. It uses the enhanced for loop syntax introduced in version 1.5 of the Java programming language. Part One . AssetManager - 已知单个文件处理不能大于Zip格式压缩存放。 二、ListView - 这个作法可能会出现你的1行半。 三、Zip 处理类对文件名编码无法识别,也没有提供显示的设置方法,在 try { //dosomething } finally { os.close(); // 显示的使用 } Cursor而言,在移动位置时首先判断 close方法,如果重用,可以使用requery方法再次查询。 五、 deprecated 字样的,常规情况下是有更好的方法可以替代,短期内可以放心使用。这些方法一般高版本的Android放弃某些 18 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang Notification的Activity,Broardcast没有测试过,中途需要通过 HTTP协议通讯状态获取Http传输Sun Java的header可以通过Http Web Server状态可以通过 Http协议返回值常见的有400为请求错误,500为服务器内部错误,302为重定向等等。 对于Apache类有HttpPost、HttpGet和header构造通过HttpResponse 获取。 有关Server通讯类相关的开发我们将会在以后文章中做大量实例介绍。39. Android布局 一般情况下对于XML文件来编写,这样可以提高开发效率,但是考虑到代码的安全性以及执行效率,可以通过Android编译过的xml 解析器的效率对于资源占用还是比较大的,一般一个简单的 可以等价于下面的: 100px,高为自适应最小的高度 // setOrientation(VERTICAL); 设置布局为垂直 TextView textControl = new TextView(this);// 如果从一个LinearLayout为this应该换成为创建改类的"); addView( textControl, textParams ); Java处理效率比Java代码来布局你的 Android软件性能主要方法Android平台上软件的性能测试可以通过以下几种方法来分析效率瓶颈,目前Android软件开发过程中已经引入了多种测试工具包,比如Dev Tools 都可以直接反应执行性能。 1. 在模拟器上的FPS,3D图形界面的性能。 2. 一般涉及到网络应用的程序,在效率上和网速有很多关系,这里需要多次的调试才能实际了解。 3. 对于逻辑算法的效率执行,我们使用: do something long duration = System.currentTimeMillis() - start; duration保存着实际处理该方法需要的毫秒数。这里类似GetTickCount,在Symbian上都提供了高精度的性能计数器和低阶计时器,这里在Java 层这种方法对于一般的应用足以。 4. GC 效率跟踪,如果你执行的应用比较简单,可以在Logcat的 Android平台上给我们提供了丰富的多任务同步方法,但在深层上并没有过多的比如自旋锁等高级应用,不过对于appWidget 而言,他们实际的产品中都应该以多线程的方式处理,以释放DDMS中看到。 更多的调试和性能测试方法 Android中的实现Tencent推出的手机Splash Screen 载入效果,通常游戏或大型软件打开时可能需要一个释放解析资源的过程,需要一个前台的动画播放和后台的逻辑处理线程配合,当然对于简单的软件也可以加一个Android 平台上如何实现呢 首先创建一个SetContentView时直接通过Android123提示大家还要考虑好分辨率和当前设备一致,: 19 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang Handler创建一个延时的调用Intent打开最终真正的主界面Activity SplashScreen.this.startActivity(i); // 启动 SplashScreen.this.finish(); // 关闭自己这个开场屏 Activity你知多少呢Activity是Activity的生命周期比如Android123还知道ApplicationContext,而Context这个抽象类派生而来的,当然我们看到显示的是 ViewGroup,当然今天说的不是这些东西,而是很多网友来问的Android 1.5开始restartPackage可以关闭一个程序,需要加上Home 键可以看到以前程序的运行,同时可以快速的切换回来。这就是 Activity历史栈。 我们在一个普通的程序主窗口B,而窗口C,但是按下Activity的FIFO 的,阻止我们不愿意看的情况的发生则可以在打开新FLAG_ACTIVITY_NO_HISTORY,代码如下 Intent i= new Intent(this, cwj.class); i.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); //Android 开发网提示大家相关的还有 startActivity(i); Activity控制可以再 Android上的应用AJAX应用,相信对JavaScript的数据交换格式,可以直接代替Android从JSONObject。在平时应用中直接引入SOAP。 在常规使用方便 Bundle或XML的getString、put、getInt等数据类型的存取操作。Server端的布局,在http的请求处理。可以直接引入web server层的数据交换,如果你没有专业的Web 配合 MemoryFile 很多网友抱怨I/O性能不是很理想,如果不想使用MemoryFile类实现高性能的文件读写操作。Win32开发,那么它的原理就是Linux的网友可能很快就联想到了 android.os.MemoryFile这个位置,从 ? I/O需要频繁操作的,主要是和外部存储相关的MemoryFile通过将SD卡上的文件,分段映射到内存中进行修改处理,这样就用高速的ROM或Android 手机而言同时还减少了电量消耗。Object上继承,通过C底层执行。 MemoryFile(String name, int length) ,这里第二个参数为文件大小,需要说明的是 MemoryFile和传统的ashmem会从内核中回收资源。毕竟目前部分低端机型的 ashmem清理内存,线程安全同步的方式。Linux内部 InputStream getInputStream() 返回读取的内容用InputStream保存OutputSream写入到 boolean isPurgingAllowed() // 判断是否允许清理 下面就是我们熟悉的,读写细节,主要是对字符数组的操作,这里大家要计算好每个文件类型的占用,同时考虑到效率对于自己分配的大小考虑粒度对齐。 具体的实际应用, 20 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang -Android字符串处理类Android为我们提供了一个简单实用的android.text.TextUtils的类,主要的功能如下 是否为空字符 public static String[] split (String text, String expression) , String.split() returns [''] when the string to be split is empty. This returns []. This does not remove any empty strings from the result. For example split("a,", "," ) returns {"a", ""}. 拆分字符串使用正则 确定大小写是否有效在当前位置的文本 使用 static String TextUtils.htmlEncode(String s) String字符串, 在Java层处理Android开发网给大家一个方便的类,可以处理String字符串,在效率上,我们使用了字符串拼接BefferedReader类实现一个缓存。 private String Stream2String(InputStream is) { BufferedReader reader = new BufferedReader(new InputStreamReader(is), 16*1024); // 强制缓存大小为Java 类默认为 sb.append(line + "\n"); } } catch (IOException e) { e.printStackTrace(); } finally { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } return sb.toString(); } 47. layout资源包含, 有时候我们在一个xml文件中复用过去的布局文件,但是和常规的使用不同的是,需要加上类似包含头文件一样的layout文件夹下的 这样下,完整的如下,大家可以试一试。 21 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang 48.Android控件开发之 在ToggleButton控件,虽然它的功能和ToggleButton原本有图片装饰,通过Button为基类的Checkable来实现。 public abstract class extends implements Checkable { private boolean mChecked; // 状态是否选中 private OnCheckedChangeListener mOnCheckedChangeListener; // 选中状态改变监听 private static final int[] CHECKED_STATE_SET = { R.attr.state_checked }; public CompoundButton(Context context, AttributeSet attrs) { this(context, attrs, 0); } TypedArray a = context.obtainStyledAttributes( attrs, com.android.internal.R.styleable.CompoundButton, defStyle, 0); boolean checked = a .getBoolean(com.android.internal.R.styleable.CompoundButton_checked, false); setChecked(checked); GC } @Override public boolean performClick() { toggle(); return super.performClick(); } public void setChecked(boolean checked) { if (mChecked != checked) { mChecked = checked; refreshDrawableState(); // 更新当前状态的按钮图标 if (mBroadcasting) { return; } 22 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang mBroadcasting = false; } } void setOnCheckedChangeWidgetListener(OnCheckedChangeListener listener) { mOnCheckedChangeWidgetListener = listener; } public void setButtonDrawable(int resid) { if (resid != 0 && resid == mButtonResource) { return; } Drawable d = null; if (mButtonResource != 0) { d = getResources().getDrawable(mButtonResource); } setButtonDrawable(d); } refreshDrawableState(); } if (!populated) { int resourceId = 0; if (mChecked) { resourceId = R.string.accessibility_compound_button_selected; } else { resourceId = R.string.accessibility_compound_button_unselected; } String state = getResources().getString(resourceId); event.getText().add(state); event.setChecked(mChecked); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int y = 0; 23 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang buttonDrawable.setBounds(0, y, buttonDrawable.getIntrinsicWidth(), y + height); buttonDrawable.draw(canvas); } } @Override protected void drawableStateChanged() { //android123 提示状态改变时需要更换按钮的图标 @Override protected boolean verifyDrawable(Drawable who) { return super.verifyDrawable(who) || who == mButtonDrawable; } SavedState(Parcelable superState) { super(superState); } private SavedState(Parcel in) { super(in); checked = (Boolean)in.readValue(null); } @Override public String toString() { return "CompoundButton.SavedState{" + Integer.toHexString(System.identityHashCode(this)) + " checked=" + checked + "}"; } public SavedState[] newArray(int size) { return new SavedState[size]; } }; } SavedState ss = new SavedState(superState); @Override public void onRestoreInstanceState(Parcelable state) { SavedState ss = (SavedState) state; super.onRestoreInstanceState(ss.getSuperState()); setChecked(ss.checked); requestLayout(); } } 24 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang 从上面来看我们知道Android开发网提醒大家而CompuundButton增加的给用户而言主要是开关的文字显示。public class ToggleButton extends CompoundButton { private CharSequence mTextOn; private CharSequence mTextOff; private Drawable mIndicatorDrawable; public ToggleButton(Context context, AttributeSet attrs) { this(context, attrs, com.android.internal.R.attr.buttonStyleToggle); } @Override public void setChecked(boolean checked) { super.setChecked(checked); syncTextState(); } public CharSequence getTextOn() { return mTextOn; } public CharSequence getTextOff() { return mTextOff; } @Override public void setBackgroundDrawable(Drawable d) { super.setBackgroundDrawable(d); updateReferenceToIndicatorDrawable(d); } 49. AsyncTask实例代码演示 上次我们讲到了AsyncTask异步任务类,相对于线程来说Android的AsyncTask类来处理,在Web服务器Favicon图标。 首先 AsyncTaskdoInBackgroundonProgressUpdateonPostExecute 最终我们执行 Android浏览器中下载: 25 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang public DownloadTouchIcon(BrowserActivity activity, ContentResolver cr, Cursor c, WebView view) { // 构造方法 public DownloadTouchIcon(ContentResolver cr, Cursor c, String url) { //实现本类的构造 @Override public Bitmap (String... values) { // 返回 String url = values[0]; HttpClientParams.setRedirecting(client.getParams(), true); // 处理 if (response.getStatusLine().getStatusCode() == 200) { // 如果InputStream中,因为是二进制内容Bitmap ,这里使用了decodeStream content, null, null); return icon; } } } } catch (IllegalArgumentException ex) { request.abort(); } catch (IOException ex) { request.abort(); } finally { client.close(); } return null; } @Override public void onPostExecute(Bitmap icon) { if (mActivity != null) { mActivity.mTouchIconLoader = null; } 最终图标要保存到浏览器的内部数据库中,系统程序均保存为Browser也不例外,因为图片是二进制的所以使用字节数组存储数据库的 Bitmap压缩成100%存储SQLite的raw sql代替Browser.BookmarkColumns.TOUCH_ICON字段 if (mCursor.moveToFirst()) { do { mContentResolver.update(ContentUris.withAppendedId(Browser.BOOKMARKS_URI, mCursor.getInt(0)),values, null, null); } while (mCursor.moveToNext()); } mCursor.close(); } } 26 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang Android开发网通过两个Android平台上AsyncTask、HTTP以及Google如何去实现 View实例 针对View的直接构造很多网友没有实战经验,本次AnalogClock类来理解AnalogClock就是: private Drawable mHourHand; // 时针 private Drawable mDial; // 表盘背景 private int mDialWidth; // 表盘宽度 Handler类实现更新时间 public AnalogClock(Context context, AttributeSet attrs) { this(context, attrs, 0); } mDial = a.getDrawable(com.android.internal.R.styleable.AnalogClock_dial); // 加载表盘资源 mHourHand = a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_hour); //加载时针图片资源 mMinuteHand = a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_minute); //加载分针图片 mCalendar = new Time(); //获取当前系统时间 mDialWidth = mDial.getIntrinsicWidth(); // 获取表盘图片的宽度 } onAttachedToWindow if (!mAttached) { mAttached = true; IntentFilter filter = new IntentFilter(); // 注册一个消息过滤器,获取时间改变、时区改变的 filter.addAction(Intent.ACTION_TIME_TICK); filter.addAction(Intent.ACTION_TIME_CHANGED); filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); mCalendar = new Time(); @Override 27 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang protected void () { super.onDetachedFromWindow(); if (mAttached) { getContext().unregisterReceiver(mIntentReceiver); // 反注册消息过滤器 @Override protected void (int widthMeasureSpec, int heightMeasureSpec) { float hScale = 1.0f; float vScale = 1.0f; if (heightMode != MeasureSpec.UNSPECIFIED && heightSize < mDialHeight) { vScale = (float )heightSize / (float) mDialHeight; } setMeasuredDimension(resolveSize((int) (mDialWidth * scale), widthMeasureSpec), resolveSize((int) (mDialHeight * scale), heightMeasureSpec)); } 主要的绘图重写onDraw方法,我们可以看到通过 onDraw boolean changed = mChanged; if (changed) { mChanged = false; } int x = availableWidth / 2; int y = availableHeight / 2; boolean scaled = false; if (changed) { dial.setBounds(x - (w / 2), y - (h / 2), x + (w / 2), y + (h / 2)); } dial.draw(canvas); android123提示就是那个时针图片的旋转角度,直接反应的就是表盘上那个针的时间 canvas.save(); canvas.rotate(mMinutes / 60.0f * 360.0f, x, y); // 同理,分针旋转的角度 final Drawable minuteHand = mMinuteHand; 28 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang if (changed) { w = minuteHand.getIntrinsicWidth(); h = minuteHand.getIntrinsicHeight(); minuteHand.setBounds(x - (w / 2), y - (h / 2), x + (w / 2), y + (h / 2)); } minuteHand.draw(canvas); canvas.restore(); private void onTimeChanged() { // 获取时间改变,计算当前的时分秒 int hour = mCalendar.hour; int minute = mCalendar.minute; int second = mCalendar.second; private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { // 监听获取时间改变 onTimeChanged(); //获取新的时间onDraw方法实现分针时针的走动 看了本例根据,Android123 提醒网友的是可能对于电池,以及系统运行效率产生一定的影响,不过作为练习大家可以试一试。51. ArrayList LinkedList Set HashMap介绍 在SQLite 或效率以及类库不完善的SharedPreferences不具备数据枚举方法,如果仅仅是一个Int数组可以通过一个标记分割设计外,我们还是主要来看看Java提供的基础数据类型辅助类C++ 的Boost库可以略过本文。 在Collection和List和Collection接口;同时用ArrayList、List接口,TreeSet实现HashTable、TreeMap实现 Array的Array,并且“sychronized”的,这个也是ArrayList的唯一的区别。 ArrayList :同Array的,但是不同的是Vector优越一些。 List,它不是基于Array性能的限制。当对nextNode的相关信息就可以实现了所以它适合于进行频繁进行插入和删除操作。这就是 List中只能容纳单个不同类型的对象组成的表,而不是Value键值对。例如: List中可以有相同的元素,例如 [ tom,koo,too,koo ]; 3. 所有的null元素,例如 Array的Vector,LinkedList(链表)适合添加,删除操作。Set同Collection接口,但是他们的实现方式却大不一样。Array为基础。但是HashMap 的基础上来实现的,这个就是List的根本区别。 HashSet :HashMap中的Set的对应存储项,key是不能有重复的。HashSet中的对象需要实现0。 TreeSet:将放入其中的元素按序存放,这就要求你放入其中的对象是可排序的。HashSet的根本是SortedMap来实现的。 Set 总结:Map( 2. Set 中的元素是不能重复的,如果使用e1、e1.equals( Map有两种比较常用的实现:HashMap和 29 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang firstKey(),lastKey()等。 HashMap 和 HashMap允许空(key)或值(Hashtable。null)键(value)。 有关更多实用的 android.os.ConditionVariable,它可以帮助SDK上的介绍Java位于 notify() ,这个类可以等待自己,这就意味着 block() 可能会假死ConditionVariable 类的 block() 之前, 4个方法 boolean block(long timeout) 阻止当前线程知道条件是long timeout为超时设置,Win32开发,这个方法类似 open ,是上面的无超时等待重载版本。 void close() 重置条件为 . public ConditionVariable (boolean state) ,如果为opened,如果为closed. ,默认close(). Eclipse调试技巧Google提供的Eclipse上很轻松的调试DDMS标签,选择Debug Process(调试进程Update Threads(更新线程Update Heap(更新堆Cause GC(引起垃圾回收Stop Process(停止进程Screen Capture(屏幕截图Reset adb(重启 这里我们就可以很好的观察DDMS 框架下进行的,日程开发的程序是无法执行调用的。如果遇到reset adb来重新启动,整个界面如图 很多网友对于一些常的Eclipse中的SDK中提供的Android程序,这里可以更直观的现实设备的各种信息,除了VM Heap堆查看、Device中可以找到File Explorer 进行文件同步操作,使用 快速的过滤radio state、程序状态android-sdk-windows-1.5_r1\tools\ddms.bat找到,目前我们测试环境为CentOS中的操作,如图 Android软件性能上需要多加考虑。首先GC处理机制直接影响到内存释放和整个平台运行的流畅度。 1. 节省电量 手机软件必须考虑的问题是省电,如果需要大型处理尽量由服务器处理,直接把结果返回到手持设备上。多线程也是一种奢侈的使用,但是Android在Thread查看。 2. 内存占用 在DDMS中可以看到,Android开发网提示的是StringBuilder代替png图片上截取,或者放在 30 / 31 WWW.CNMSDN.COM This document is downloaded from Share.cnmsdn.com Created By wzfyang Dev Tools和Logcat查看。当然模拟器自带的CPU占用率,内存使用量,在单元测试时需要多加分析。Android开发工具 ADB、Logcat外,今天这个名为Android开发调试工具隐藏在Dev Tools,运行后可以看到有很多条目,比如Show CPU Usage这样的实用功能显示Android 开发人员分析当前软件性能情况,今天就分析下: Enable ADB 启用) Show running processs (显示运行中的进程) Android开发网友情提示开启这些选项后可能会影响运行效率,这些探测选项也是 activities) Show CPU usage (显示) Show background (显示北京LED开启) Show GTalk service connection status (显示) 下载更多相关源代码、电子书、工具包请访问:http://share.cnmsdn.com/ 我分享的更多移动开发资源:http://share.cnmsdn.com/user/wzfyang Powered by TCPDF (www.tcpdf.org) 31 / 31
还剩30页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 6 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

tiney

贡献于2013-12-04

下载需要 6 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf