有关云计算的瞎想

  1. android单实例运营方式

明日接受了关于09年中华第四届云总结大会的邮件,与会者可谓人才济济啊。

我们都了然Android平台没有义务管理器,而其间App维护者贰个Activity
history
stack来贯彻窗口显示和销毁,对张晓芸规从飞快情势运营来看都以startActivity大概会动用FLAG_ACTIVITY_NEW_TASK标记来打开一个新窗口,比如Launcher,所以考虑单职分的完毕形式相比较简单,首先Android123校正下大家一种错误的法子就是直接在androidmanifest.xml的application节点中进入android:launchMode=”singleInstance”那句,其实这么将不会起到其他作用,Apps内部维护的历史栈成效于Activity,我们务必在activity节点中加入android:launchMode=”singleInstance”
那句才能保障单实例,当然一般均加在主程序运行窗口的Activity。

最早知道云总结这么些定义是二零一八年在场微软技能大会时知道的,也是在那里似懂非精晓知道了些云总结大约是咋回事儿。
貌似正是集结网络上的硬件财富,由原本单台服务器提供服务成为了由用户本人选拔选择软件服务器而重组的多台服务器提供软件服务的情势。

  1. px像素怎样转为dip设备独立像素

作者想开了网站先后、网游。。。大型的网站和网游也是由多台服务器组成的服务阵列,只不过对用户而言应用软件稍卡片机一了点,那看似正是云总括的最简方式吗?!
从网游想开去,今后真有提供云总结服务的厂商,那会不会也像网游那样,出现过多私服啊,O(∩_∩)O~

近来有网络好友问怎么将px像素转为dip独立设备像素,由于Android的配备分辨率众多,近年来主流的为wvga,而过多老的设施为hvga甚至低端的qvga,对于包容性来说使用dip无非是比较有利的,由于他和分辨率非亲非故和显示器的密度大小有关,所以推举应用。  px=
(int) (dip*density+0.5f)
//那里android开发网提醒大家多多网络好友获得density(密度)的方式存在难题,从财富中收获的是静态定义的,一般为1.0对此HVGA是刚刚的,而对于wvga那样的应该从WindowsManager中取得,WVGA为1.5 那里能够再补充一下dip,sip的学识

还有此n年前
提到的网络操作系统,貌似也是其一概念种类下的。谷歌(Google)不是要做个吗基于搜索引擎的网络操作系统跟微软抗衡么,后来不知咋就没啥动静了。。。

  1. Android中动态改变ImageView大小

指望真等云总括发展兴起的那天,咱国家的网络能提供nM以上的下载速度,nnM以上的上传速度,还得包月、包年。。。。开支是还是不是能降下来点啊

众多网上好友或然发今后layout.xml文件中定义了ImageView的相对化大小后,无法动态修改之后的大大小小突显,其实Android平台在设计UI控件时考虑到这一个标题,为了适应分化的Drawable能够经过在xml的相干ImageView中进入android:scaleType=”fitXY”
那行即可,但因为运用了缩放恐怕会造成近来UI有所变形。使用的前提是限制ImageView所在的层,能够行使三个内嵌的办法限制呈现。

其它,大公司好像不差钱买多少个服务器,雇几人爱抚他的多少,假如她们的COO担心自身的多寡安全的话。银行敢用云总结么?倒霉说。。。

  1. 怎么判定Android手提式有线电话机当前是或不是联网?

对此小企和个人用户呢,小软件还得装了当地,不然用个软件还得上网,除非到时候上网速度跟地面速度没啥分化,那得等到什么日期啊。。。

若是拟开发五个互连网接纳的顺序,首先考虑是还是不是衔接互联网,在Android手提式有线话机中判断是还是不是联网能够透过
ConnectivityManager
类的isAvailable()方法判断,首先获得互联网通讯类的实例
ConnectivityManager
cwjManager=(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SE路虎极光VICE);
,使用cwjManager.getActiveNetworkInfo().isAvailable();
来重回是不是可行,若是为True则意味着目前Android手机已经联网,可能是WiFi或GP奥迪Q5S、HSDPA等等,具体的能够通过ConnectivityManager
类的getActiveNetworkInfo()
方法判断详细的衔接方式,需求小心的是关于调用须要投入<uses-permission
android:name=”android.permission.ACCESS_NETWORK_STATE”></uses-permission>
这一个权力,android开发网提示大家在真机上Market和Browser程序都使用了那一个点子,来判定是或不是一而再,同时在有的网络超时的时候也足以检查下网络连接是还是不是留存,以防浪费手机上的电力财富。

大软件呢?对于广大盗版用户来说舍得花钱买极度服务么?依旧装了地点最棒使用来的管事。。。

  1. Drawable、Bitmap、Canvas和Paint的关系

 云总括,想说爱你不易于吗。。。图片 1

过多网上朋友刚刚开端学习Android平台,对于Drawable、Bitmap、Canvas和Paint它们中间的定义不是很驾驭,其实它们除了Drawable外早在Sun的J2ME中就已经出现了,然则在Android平博洛尼亚,Bitmap、Canvas相关的都抱有扭转。 
 首先让我们了解下Android平斯特拉斯堡的展现类是View,然则还提供了尾部图形类android.graphics,明天所说的这几个均为graphics底层图形接口。 
 Bitmap –
称作位图,一般位图的文件格式后缀为bmp,当然编码器也有诸多如PRADOGB56五 、HighlanderGB888。作为一种逐像素的彰显对象执行功用高,但是缺点也很肯定期存款款和储蓄功效低。大家知晓为一种存款和储蓄对象比较好。 
 Drawable –
作为Android平下通用的图纸对象,它能够装载常用格式的图像,比如GIF、PNG、JPG,当然也支撑BMP,当然还提供一些高级的可视化对象,比如渐变、图形等。 
 Canvas –
名为画布,我们得以看成是一种处理进程,使用各样格局来管理Bitmap、GL只怕帕特h路径,同时它能够匹配Matrix矩阵类给图像做旋转、缩放等操作,同时Canvas类还提供了裁剪、选用等操作。 
  Paint –
大家能够把它看成3个图案工具,比如画笔、画刷。他保管了种种图案工具的书体、颜色、样式。 
 借使波及一些Android游戏开发、显示特效能够透过这一个底层图形类来火速落到实处自个儿的选拔。 

  1. Activity切换导致的onCreate重复执行

一对网络朋友会发现Activity在切换来后台或布局从横屏RAV4SCAPE切换成PO福特ExplorerTRAIT,会重新切换Activity会触发三回onCreate方法,大家得以在androidmanifest.xml中的activit成分参预那特性情android:configChanges=”orientation|keyboardHidden”
即可,比如 <activity
android:name=”.android123″ android:configChanges=”orientation|keyboardHidden”android:label=”@string/app_name”> 
 同时在Activity的Java文件中重载onConfigurationChanged(Configuration
newConfig)那个法子,那样就不会在布局切换或窗口切换时重载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
     }
    }

  1. Android的ImageButton问题

诸多网络好友对Android提供的ImageButton有个难题,当展现Drawable图片时就不会再展现文字了,其实消除的措施有两种,第壹种正是图片中就写入文字,可是如此解决会扩充程序体量,同时硬编码格局会影响多国语言的揭露。第三种缓解情势很简短,通过分析可以看出ImageButton的layout,大家得以一直直接接轨,添加贰个TextView,对齐格局为左侧即可落成ImageButton帮衬文字左侧突显。

  1. Android代码优化技术

1.Java内部存款和储蓄器控制 
 对于字符串操作而言倘若急需连加那样的操作提出选用StringBuilder,经过调节和测试不难察觉只要您的字符串每一回连加,使用String须要的内部存款和储蓄器花费会远超过StringBuilder,然后Android手机常规的运转内部存储器差不离在128MB左右,对于运维多义务就供给考虑了,Android开发网提示因为Java有GC不需求手动释放那么分配的时候就要十分的小心,频仍的GC操作照旧是很影响属性的,在调节和测试时大家可以透过logcat查看内部存款和储蓄器释放景况。 
 2.循环使用 
 平日在造访1个性能的时候效用远比二个恒定变量低,假如您的轮回推测次数日常超越5,假诺xxx.GetLength()方法的值一般超越5,推荐那样写,比如 
 for(int i=0;i<xxx.GetLength();i++) 
 那里xxx.GetLength在每趟循环都要调用,必然会潜移默化程序成效,在嬉戏开发中显得尤为肯定,创新的法门应该为 
 int j=xxx.GetLength()    for(int i=0;i<j;i++)   3.图形的优化 
 在Android平莱比锡2维图像处理库BitmapFactory做的可比智能,为了削减文件体量和频率,平时不用过多能源文件,而把众多小图片放在一个图形中,有切片的方法来成功,在J2ME中我们如此是为了将少文件头而消除MIDP那些设备的题材,而Android中固然机型硬件配备都比较高,有关Android
G1硬件配置能够参考G1有线电话参数以及评测,可是当财富多时如此的运转成效照旧左右逢原的,至少Dalvik优化的还不是很够。

  1. Android开发进阶之NIO非阻塞包(一)

对于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三个包理解。http://www.android123.com.cn/androidkaifa/695.html

问询下那种技能,看看在当时要做的花色中是还是不是用赢得

  1. Android Theme和Styles内部定义解析

昨天大家讲到的关于在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文件夹下放1个图形名为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>
等等。

11.Android JSON解析示例代码

发源谷歌(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,
Update瑟维斯.class)); //幸免ANQX56,所以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 = new ComponentName(this,
WordWidget.class);
            AppWidgetManager manager =
AppWidgetManager.getInstance(this);
            manager.updateAppWidget(thisWidget, updateViews);
        }         public RemoteViews buildUpdate(Context context) {
            // Pick out month names from resources
            Resources res = context.getResources();
            String[] monthNames =
res.getStringArray(R.array.month_names);              Time today =
new Time();
            today.setToNow();             String pageName =
res.getString(R.string.template_wotd_title,
                    monthNames[today.month], today.monthDay);
            RemoteViews updateViews = null;
            String pageContent = “”;             try {
                SimpleWikiHelper.prepareUserAgent(context);
                pageContent =
SimpleWikiHelper.getPageContent(pageName, false);
            } catch (ApiException e) {
                Log.e(“WordWidget”, “Couldn’t contact API”, e);
            } catch (ParseException e) {
                Log.e(“WordWidget”, “Couldn’t parse API response”,
e);
            }             Pattern pattern =
Pattern.compile(SimpleWikiHelper.WORD_OF_DAY_REGEX);
//正则表明式处理,有关定义见下边包车型大巴SimpleWikiHelper类
            Matcher matcher = pattern.matcher(pageContent);
            if (matcher.find()) {
                updateViews = new
RemoteViews(context.getPackageName(), R.layout.widget_word);       
         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());                 String definePage =
res.getString(R.string.template_define_url,
                        Uri.encode(wordTitle));
                Intent defineIntent = new Intent(Intent.ACTION_VIEW,
Uri.parse(definePage));
//这里是打开相应的网页,所以Uri是http的url,action是view即打开web浏览器
                PendingIntent pendingIntent =
PendingIntent.getActivity(context,
                        0 /* no requestCode */, defineIntent, 0 /*
no flags */);
                updateViews.setOnClickPendingIntent(R.id.widget,
pendingIntent); //单击Widget打开Activity             } else { 
                updateViews = new
RemoteViews(context.getPackageName(), R.layout.widget_message);
                CharSequence errorMessage =
context.getText(R.string.widget_error);
                updateViews.setTextViewText(R.id.message,
errorMessage);
            }
            return updateViews;
        }         @Override
        public IBinder onBind(Intent intent) {
            // We don’t need to bind to this service
            return null;
        }
    }
}   有关网络通信的实体类,以及一些常量定义如下:   public class
SimpleWikiHelper {
    private static final String TAG = “SimpleWikiHelper”;     public
static final String WORD_OF_DAY_REGEX =
          
 “(?s)\\{\\{wotd\\|(.+?)\\|(.+?)\\|([^#\\|]+).*?\\}\\}”; 
   private static final String WIKTIONARY_PAGE =
          
 “http://en.wiktionary.org/w/api.php?action=query&prop=revisions&titles=%s&

  •             “rvprop=content&format=json%s”;     private static final
    String WIKTIONARY_EXPAND_TEMPLATES =
                “&rvexpandtemplates=true”;     private static final int
    HTTP_STATUS_OK = 200;     private static byte[] sBuffer = new
    byte[512];     private static String sUserAgent = null;      public
    static class ApiException extends Exception {
            public ApiException(String detailMessage, Throwable throwable)
    {
                super(detailMessage, throwable);
            }         public ApiException(String detailMessage) {
                super(detailMessage);
            }
        }     public static class ParseException extends Exception {
            public ParseException(String detailMessage, Throwable
    throwable) {
                super(detailMessage, throwable);
            }
        }     public static void prepareUserAgent(Context context) {
            try {
                // Read package name and version number from manifest
                PackageManager manager = context.getPackageManager();
                PackageInfo info =
    manager.getPackageInfo(context.getPackageName(), 0);
                sUserAgent =
    String.format(context.getString(R.string.template_user_agent),
                        info.packageName, info.versionName);         }
    catch(NameNotFoundException e) {
                Log.e(TAG, “Couldn’t find package information in
    PackageManager”, e);
            }
        }     public static String getPageContent(String title, boolean
    expandTemplates)
                throws ApiException, ParseException {
            String encodedTitle = Uri.encode(title);
            String expandClause = expandTemplates ?
    WIKTIONARY_EXPAND_TEMPLATES : “”;         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);
            }
        }     protected static synchronized String getUrlContent(String
    url) throws ApiException {
            if (sUserAgent == null) {
                throw new ApiException(“User-Agent string must be
    prepared”);
            }         HttpClient client = new DefaultHttpClient();
            HttpGet request = new HttpGet(url);
            request.setHeader(“User-Agent”, sUserAgent); //设置客户端标识 
           try {
                HttpResponse response = client.execute(request);          
      StatusLine status = response.getStatusLine();
                if (status.getStatusCode() != HTTP_STATUS_OK) {
                    throw new ApiException(“Invalid response from server:
    ” +
                            status.toString());
                }             HttpEntity entity = response.getEntity();
                InputStream inputStream = entity.getContent();
    //获取HTTP重返的数据流             ByteArrayOutputStream content = new
    ByteArrayOutputStream();             int readBytes = 0;
                while ((readBytes = inputStream.read(sBuffer)) != -1) {
                    content.write(sBuffer, 0, readBytes);
    //转化为字节数组流
                }             return new String(content.toByteArray());
    //从字节数组营造String
            } catch (IOException e) {
                throw new ApiException(“Problem communicating with API”,
    e);
            }
        }
    }
    有关任何每一天维基的widget例子相比较不难,主借使支援我们累积常用代码,领悟Android平台
    JSON的处理格局,究竟很多Server依旧Java的。

12.Android中动用定时器TimerTask类介绍

在Android平纽伦堡必要反复按周期执行办法能够运用Java上自带的TimerTask类,TimerTask绝对于Thread来说对于财富消耗的更低,除了接纳Android自带的AlarmManager使用Timer定时器是一种更好的消除格局。
大家需要引入import java.util.Timer; 和 import java.util.TimerTask;
private Timer  mTimer = new Timer(true);
private TimerTask mTimerTask;     mTimerTask = new TimerTask()
    {
      public void run()
      {
       Log.v(“android123″,”cwj”);
      }        
     };
     mTimer.schedule(mTimerTask,
四千,一千);  //在1秒后每5秒执行二回定时器中的方法,比如本文为调用log.v打字与印刷输出。 
 假如想收回能够调用下边方法,裁撤定时器的实施   
while(!mTimerTask.cancel());
      m提姆er.cancel(); 
 最终Android123提示我们,倘若拍卖的事物比较耗费时间依然开个线程比较好,Timer照旧会卡住主线程的实践,更像是一种音讯的实践办法。当然比Handler的postDelay等艺术更契合处理安插职务。

13.Android利用Icon大小在分化分辨率下定义

对于Android平台来说,分裂分辨率下Icon的轻重设计有着差异的渴求,对于近期主流的HDPI即WVGA级别来说,日常hdpi的运用icon大小为72×72,而正式的mdpi即hvga为48×48,对于当前一加和Nokia推出的一些QVGA的选拔了ldpi,图标为32×32,常见的Android图标大小设计规范如下表所示: Launcher
36 x 36 px
48 x 48 px
72 x 72 px Menu
36 x 36 px
48 x 48 px
72 x 72 px Status Bar
24 x 24 px
32 x 32 px
48 x 48 px Tab
24 x 24 px
32 x 32 px
48 x 48 px Dialog
24 x 24 px
32 x 32 px
48 x 48 px List View
24 x 24 px
32 x 32 px
48 x 48 px 
 对于android界面设计的安全色,如下表 图片 2 而对于系统自带默许程序的图标,下边为png的晶莹格式,直接鼠标右键另存为即可 图片 3

看望sdk文书档案上的关于界面图标的详实表达。 14.Android控件美化Shape你会用吗?

一经您对Android系统自带的UI控件感觉不够知足,能够尝尝下自定义控件,大家就以Button为例,很早在此之前Android123就写到过Android
Button按钮控件美化方法里面涉及了xml的selector构造。当然除了选取drawable那样的图片外前天Android开发网谈下自定义图形shape的办法,对于Button控件Android上支撑以下三种个性shape、gradient、stroke、corners等。 
 我们就以当下系统的Button的selector为例说下:           <shape>
            <gradient
                android:startColor=”#ff8c00″
                android:endColor=”#FFFFFF”
                android:angle=”270″ />
            <stroke
                android:width=”2dp”
                android:color=”#dcdcdc” />
            <corners
                android:radius=”2dp” />
            <padding
                android:left=”10dp”
                android:top=”10dp”
                android:right=”10dp”
                android:bottom=”10dp” />
        </shape> 
   对于地方,那条shape的定义,分别为渐变,在gradient中startColor属性为初始的颜色,endColor为渐变利落的水彩,下边包车型大巴angle是角度。接下来是stroke可以领悟为边缘,corners为拐角那里radius属性为半径,最后是相对地方属性padding。
对于1个Button完整的概念能够为   <?xml version=”1.0″
encoding=”utf-8″?>
<selector
    xmlns:android=”http://schemas.android.com/apk/res/android"&gt;
    <item android:state_pressed=”true” >
        <shape>
            <gradient
                android:startColor=”#ff8c00″
                android:endColor=”#FFFFFF”
                android:angle=”270″ />
            <stroke
                android:width=”2dp”
                android:color=”#dcdcdc” />
            <corners
                android:radius=”2dp” />
            <padding
                android:left=”10dp”
                android:top=”10dp”
                android:right=”10dp”
                android:bottom=”10dp” />
        </shape>
    </item>     <item android:state_focused=”true” >
        <shape>
            <gradient
                android:startColor=”#ffc2b7″
                android:endColor=”#ffc2b7″
                android:angle=”270″ />
            <stroke
                android:width=”2dp”
                android:color=”#dcdcdc” />
            <corners
                android:radius=”2dp” />
            <padding
                android:left=”10dp”
                android:top=”10dp”
                android:right=”10dp”
                android:bottom=”10dp” />
        </shape>
    </item>     <item>       
        <shape>
            <gradient
                android:startColor=”#ff9d77″
                android:endColor=”#ff9d77″
                android:angle=”270″ />
            <stroke
                android:width=”2dp”
                android:color=”#fad3cf” />
            <corners
                android:radius=”2dp” />
            <padding
                android:left=”10dp”
                android:top=”10dp”
                android:right=”10dp”
                android:bottom=”10dp” />
        </shape>
    </item>
</selector>
注意Android123唤起大家,以上多少个item的不一致重若是反映在state_pressed按下或state_focused得到宗旨时,当当来判断呈现怎么类型,而从不state_xxx属性的item能够视作是例行状态下。

  1. Android开发者应该保证以下特质

Android123推荐介绍新手应该遵照   1. 深读SDK文书档案   2.
深读SDK的API德姆o和Samples   3. 左右GIT开源代码   4.
多了然Android开源项目,学习外人的手法写程序。

  1. Android数组排序常见情势

  Android的数组排序格局大多选择了Sun原生的Java
API完结,常用的有Comparator接口完结compare方法和Comparable接口的compareTo方法,大家对于1个数组列表比如ArrayList能够透过那八个接口进行排序和比较,那里Android123给大家3个例证
private final Comparator cwjComparator = new Comparator() {       
 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);
        }
    }; 大家的ArrayList对象名为mList,则执行排序能够调用方法
Collections.sort(mList, cwjComparator);

17.Android控件TextProgressBar进度条上显文字

Android系统的进程条控件暗许的安顿的不是很周到,比如没有包括文字的突显,那么怎么着在Android进程条控件上展现文字吗?
来自谷歌(Google)内部的代码来打探下,首要利用的addView这样的点子通过覆盖一层Chronometer秒表控件来落到实处,整个代码如下 
  public class TextProgressBar extends RelativeLayout implements
OnChronometerTickListener {
    public static final String TAG = “TextProgressBar”;
    static final int CHRONOMETER_ID = android.R.id.text1;
    static final int PROGRESSBAR_ID = android.R.id.progress;
    Chronometer mChronometer = null;
    ProgressBar mProgressBar = null;
    long mDurationBase = -1;
    int mDuration = -1;     boolean mChronometerFollow = false;
    int mChronometerGravity = Gravity.NO_GRAVITY;
    public TextProgressBar(Context context, AttributeSet attrs, int
defStyle) {
        super(context, attrs, defStyle);
    }     public TextProgressBar(Context context, AttributeSet attrs)
{
        super(context, attrs);
    }     public TextProgressBar(Context context) {
        super(context);
    }     //Android开发网提示关键部分在此间     @Override
    public void addView(View child, int index, ViewGroup.LayoutParams
params) {
        super.addView(child, index, params);
        int childId = child.getId();
        if (childId == CHRONOMETER_ID && child instanceof
Chronometer) {
            mChronometer = (Chronometer) child;
            mChronometer.setOnChronometerTickListener(this);
            // Check if Chronometer should move with with
ProgressBar
            mChronometerFollow = (params.width ==
ViewGroup.LayoutParams.WRAP_CONTENT);
            mChronometerGravity = (mChronometer.getGravity() &
Gravity.HORIZONTAL_GRAVITY_MASK);
        } else if (childId == PROGRESSBAR_ID && child instanceof
ProgressBar) {
            mProgressBar = (ProgressBar) child;
        }
    }     @android.view.RemotableViewMethod
    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();
        }         int remaining = (int) (mDurationBase – now);
        mProgressBar.setProgress(mDuration – remaining);
        if (mChronometerFollow) {
            RelativeLayout.LayoutParams params;
            params = (RelativeLayout.LayoutParams)
mProgressBar.getLayoutParams();
            int contentWidth = mProgressBar.getWidth() –
(params.leftMargin + params.rightMargin);
            int leadingEdge = ((contentWidth *
mProgressBar.getProgress()) /
                    mProgressBar.getMax()) + params.leftMargin;
            int adjustLeft = 0;
            int textWidth = mChronometer.getWidth();
            if (mChronometerGravity == Gravity.RIGHT) {
                adjustLeft = -textWidth;
            } else if (mChronometerGravity ==
Gravity.CENTER_HORIZONTAL) {
                adjustLeft = -(textWidth / 2);
            }
            leadingEdge += adjustLeft;
            int rightLimit = contentWidth – params.rightMargin –
textWidth;
            if (leadingEdge < params.leftMargin) {
                leadingEdge = params.leftMargin;
            } else if (leadingEdge > rightLimit) {
                leadingEdge = rightLimit;
            }
            params = (RelativeLayout.LayoutParams)
mChronometer.getLayoutParams();
            params.leftMargin = leadingEdge;
            mChronometer.requestLayout();
        }
    }

  1. Android内部存款和储蓄器管理-SoftReference的行使

广大时候大家须求考虑Android平台上的内部存款和储蓄器管理难题,Dalvik
VM给各种进度都分配了少于的可用堆内部存款和储蓄器,当大家处理部分消耗电源的操作时只怕会产生OOM错误(OutOfMemoryError)那样的百般,Android123考察了下国内的接近马克et客户端设计,基本上都尚未行使很好的内存管理机制和缓存处理。 
 假使仔细的网络朋友也许发现Android
马克et客户端载入时,各类列表项的图标是异步刷新显示的,但当大家快速的往下滚动到一定数额比如肆十四个,再往回滚动时大概大家看出了一些App的图标又再次开首加载,当然这一过程或许是从SQLite数据库中缓存的,可是在内存中已经因而类似SoftReference的不二法门管理内部存款和储蓄器。 
 在Java中内部存款和储蓄器管理,引用分为四大类,强引用HardReference、弱引用WeakReference、软引用SoftReference和虚引用PhantomReference。它们的区分也很显明,HardReference对象是不怕虚拟机内部存款和储蓄器吃紧抛出OOM也不会促成这一引用的指标被回收,而WeakReference等更切合于一些数据不多,但体量稍微庞大的对象,在那三个引用中,它是最简单被垃圾回收的,而作者辈对于显示类似Android
马克et中各样应用的App
Icon时能够考虑采纳SoftReference来化解内部存款和储蓄器不至于急迅回收,同时当内部存款和储蓄器紧缺面临Java
VM崩溃抛出OOM前时,软引用将会强制回收内部存款和储蓄器,最终的虚引用一般没有实际意义,仅仅观看GC的活动状态,对于测试相比实用同时务必和ReferenceQueue一起使用。 
 对于一组数据,大家可以通过HashMap的办法来添加一组SoftReference对象来权且保留部分数额,同时对于供给频仍通过网络获得的不常常转移的始末,能够因此本地的文件系统或数据库来储存缓存,希望给国内做App
Store那样的客户端一些改良提议。

  1. 反射在Android开发中的利弊

鉴于Android
2.2的出产,很多新的API参与导致众多品类移植必要考虑选拔Java的反光机制Reflection来动态调用,动态调用的益处正是不须要利用引用文件,直接通过JDK中宣示好的方法直接调用,本人规律基于JVM的,从Java
1.5开首帮助,原理上正是依照类名而不实例化对象的事态下,获得对象的点子或质量而直白调用。 
 Android开发时反射能帮助大家有个别?   1.
稍微网络好友可能发现Android的SDK相比较封闭,很多敏锐的章程常规的用户无法编写翻译,大家只要翻看了代码直接在反射中宣称动态调用即可。比如很多internal或I开首的AIDL接口均能够因此反射轻松调用。 
 2.
反光对于Android123的话更关键的是考虑到应用的兼容性,大家脚下主要包容从Android
1.5到2.2的品类,API
Level从3到8足以方便的壮大,调用前大家留下三个标明位注解该API的最低以及最高的API
Level为多少能够调用。   3.
对此调节和测试Java的反射是功臣了,在Logcat中大家得以看看出错的地点一定有近似java.lang.reflect.XXX的字样,那种自检机制能够帮忙我们有利的调节和测试Android应用程序。 
 反射的弱项有啥?   1.
因为是动态执行的,效能自然没有预编写翻译时引用现有的库功效高,就如日常我们Win32支付时,能够不用h文件,直接通过GetProcAddress一样去动态获取形式的地址。当然作用要基于复杂程度而决定,一般不怎么复杂的处理质量损失也许超过二成,对于有些扑朔迷离的涉及Java自动类型转换判断,执行时间或然是一向引用的上千倍,所以最终大家调节和测试时务必考虑质量难点。 
 2. 因为反射是动态的,所以需求处理很多百般,不然Dalvik崩溃出Force
Close的可能率会大过多,很简短的1个反光就必要至少一个特别捕获,本人try-catch成效就不是很高,自然特别影响运营功能,对于Android开发我们务必考虑这个题目。 
 3.
反光因为导致代码臃肿,自然稍微复杂的多少个方法实用反射将会造成代码可读性和维护性下落,假诺很空虚的调用Android开发网强烈不引进那种措施。 
 最终要说的是Reflection并不是Java的专利,微软的.Net也同样支撑,同时更加多的动态语言如Ruby等均协助这么些性。

20.AsyncTask对比Thread加Handler

不少网民大概发现Android平台很多利用使用的都以AsyncTask,而不用Thread和Handler去更新UI,那里Android123给大家说下他们毕竟有如何分别,大家一向应有选择哪类缓解方案。从Android
1.5起来系统将AsyncTask引入到android.os包中,过去在很早1.1和1.0
SDK时其实官方将其命名为UserTask,其内部是JDK
1.5上马新增的concurrent库,做过J2EE的网上朋友大概驾驭并发库效能和强大性,比Java原始的Thread更灵活和有力,但对此轻量级的应用越来越占用系统能源。Thread是Java早期为促成四线程而安插的,相比不难不辅助concurrent中众多特点在一块儿和线程池类中须求自身去落到实处广大的东西,对于分布式应用来说更亟待协调写调度代码,而为了Android
UI的基础代谢谷歌(Google)引入了Handler和Looper机制,它们均基于新闻完毕,有事只怕新闻队列阻塞或其余原因无法精确的应用。 
 Android开发网推荐我们利用AsyncTask代替Thread+Handler的措施,不仅调用上越来越简单,经超过实际地度量更可信赖一些,谷歌在Browser中山大学量施用了异步职责作为拍卖耗费时间的I/O操作,比如下载文件、读写数据库等等,它们在精神上都离不开音信,不过AsyncTask相比较Thread加Handler更为可信,更便于维护,但AsyncTask缺点也是有个别比如一旦线程开启即dobackground方法执行后十分的小概给线程发送音讯,仅能经过事先安装好的记号来决定逻辑,当然能够透过线程的挂起等待标志位的变动来报纸发表,对于一些应用Thread和Handler以及Looper恐怕更灵活。

  1. Android Drawable叠加处理办法

大家可能知道Bitmap的附加处理在Android平罗利可以通过Canvas一层一层的画就行了,而Drawable中哪些处理啊?
除了使用BitmapDrawable的getBitmap方法将Drawable转换为Bitmap外,前几天Android123给我们说下好用简易的LayerDrawable类,LayerDrawable顾名思义正是层图形对象。上边直接用3个简易的代码表示: 
   Bitmap bm =
BitmapFactory.decodeResource(getResources(),福睿斯.drawable.cwj);
    Drawable[] array = new Drawable[3];      array[0] = new
PaintDrawable(Color.BLACK); //黑色
     array[1] = new PaintDrawable(Color.WHITE); //白色
     array[2] = new BitmapDrawable(bm); //位图财富
    LayerDrawable ld = new LayerDrawable(array);
//参数为地点的Drawable数组
        ld.setLayerInset(1, 1, 1, 1,
1);  //第三个参数1意味数组的第3个因素,为青蓝
        ld.setLayerInset(2, 2, 2, 2, 2);
//第一个参数2意味数组的第九个元素,为位图财富
    mImageView.setImageDrawable(ld); 
 上边的章程中LayerDrawable是生死攸关,Android开发网提醒setLayerInset方法原型为public
void setLayerInset (int index, int l, int t, int r, int b)
在那之中第3个参数为层的索引号,前边的多个参数分别为left、top、right和bottom。对于简易的图形合成我们得以将率先和第③层的PaintDrawable换来BitmapDrawable即可实现简单的图纸合成。

  1. onRetainNonConfigurationInstance和getLastNonConfigurationInstance

多多网上朋友可能清楚Android横竖屏切换时会触发onSaveInstanceState,而回复时会发生onRestoreInstanceState,可是Android的Activity类还有多个艺术名为onRetainNonConfigurationInstance和getLastNonConfigurationInstance那多少个艺术。 
  我们得以因此  onRetainNonConfigurationInstance 代替
onSaveInstanceState,比如距离2   @Override
  public Object onRetainNonConfigurationInstance()
{    
      
//那里需求保留的故事情节,在切换时不是bundle了,大家得以一向通过Object来顶替
      return obj;
} 在回复窗口时,大家得以不选取 onRestoreInstanceState,而顶替的是
getLastNonConfigurationInstance
方法。大家可以直接在onCreate中运用,比如   Object obj =
getLastNonConfigurationInstance(); 
   最后obj的剧情正是上次切换时的始末。 
 那里Android123提醒大家,每回Activity横竖屏切换时onCreate方法都会被触发。

  1. Android中String能源文件的format方法

多多时候我们感觉谷歌在设计Android时严守了大气MVC架构方式,能够让写公共代码、美术工作和切实逻辑开发职员独立出来。有关Android的财富文件values/strings.xml中哪些促成格式化字符串呢?
那里Android123举个简易的例子,以及最终大概会用到哪些位置。 <?xml
version=”1.0″ encoding=”utf-8″?> 
<resources> 
    <string name=”app_name”>cwj_Demo</string> 
    <string name=”hello”>android开发网</string> 
</resources>  上面是一段简单的字符串财富文件,没有用到格式化,因为比较简单直接描述了意思,当大家规划三个类似
Delete xxx File ? 的时候,大家恐怕须要在Java中动态获取 xxx
的称号,所以定义能源时选取格式化能够轻松消除,不必要一堆String去拼接或StringBuffer三个一个append那样的鲁钝方法,看例子 
   <string name=”alert”>Delete %1$s File</string> 
 那里%1$s象征那是两个字符串型的,要是是整数型能够写为%1$d,类似printf那样的格式化字符串函数,当然假使带有了多个需求格式化的剧情,则第二个能够写为%2$s或%2$d了,那么最终在Java中什么调用呢?
看下边包车型客车例子:    例一: 整数型的   <string name=”alert”>I am %1$d
years old</string>  定义的是这般的   
当然,我们杜绝意外景况,比如冒出个secret那样的string类型的,注意上边是%1$d不是%1$s,所以暗中认可标准的合并成为 
  int nAge=23;    String sAgeFormat =
getResources().getString(CRUISER.string.alert);     String sFinalAge =
String.format(sAgeFormat, nAge);      那样进行完后,就结成了 I am 23
years old,是或不是很方便啊.  当然了,上面看下String字符串时的意况. 
 例二: 字符串型的   String sName=”cwj”   String sCity=”Shanghai”   
能源定义为   <string name=”alert2″>My name is %1$s , I am form
%2$s</string>     则Java中只要求   String sInfoFormat =
getResources().getString(大切诺基.string.alert2);    String
sFinalInfo=String.format(sInfoFormat, sName, sCity);   
大家看到了全方位,整个定义类似MFC的CString::Format或Mac
OS中的NSLog,不过供给出示类似C#中那样呈现的标号参数的数字,比如%1或%n,那里数字代表参数的第n个。本行最后sFinalInfo呈现的始末为 
 My name is cwj , I am form Shanghai
。当然了您有如何不懂的地点能够来函至 android123@163.com

  1. Android工程内嵌能源文件的三种艺术

Android软件一般处理大的财富通过sdcard比如在线下载财富到sdcard,而apk中内嵌财富或二进制文件时一般接纳上边的三种艺术: 
 方法一 
 res/raw目录下存放,比如cwj.dat叁个二进制文件,大家得以读取能够间接  InputStream
is=context.getResources().openRawResource(昂科威.raw.cwj);    方法二 
 工程根目录下的assets文件夹中存放,比如assets/cwj.dat
那样我们运用下边包车型大巴代码   AssetManager am = context.getAssets();  
  InputStream is = am.open(cwj.dat); 
   那里Android123晋升大家谷歌的Android系统处理Assert有个bug,在AssertManager中无法处理单个当先1MB的文件,不然会报相当具体数值大家能够测试下传个稍大的文书,大家在两年前的篇章中有涉及,而首先种raw没那么些界定能够放个4MB的Mp3文本没难题。

  1. Android自定义View以及layout属性全攻略

对于Android系统的自定义View可能大家都熟稔了,对于自定义View的习性添加,以及Android的Layout的命名空间问题,很多网民还不是很明亮,明天Android123一起再带大家复习一下 
 CwjView myView=new CwjView(context); 
 要是用于游戏或任何窗体的界面,大家只怕直接在onCreate中setContentView(myView);
当然就算是控件,大家或者会须要从Layout的xml中扬言,比如 
 <cn.com.android123.CwjView
   android:layout_width=”wrap_content”
   android:layout_height=”wrap_content”
  />   当然,大家也得以直接从父类表明比如   <View
class=”cn.com.android123.CwjView”
   android:layout_width=”wrap_content”
   android:layout_height=”wrap_content”
  />
上面大家仅用了父类View的多个属性,均出自android命名空间,而名称为layout_width或layout_height,大家自定义的控件可能有更加多的成效,比如 
   <cn.com.android123.CwjView
   android:layout_width=”wrap_content”
   android:layout_height=”wrap_content”
  cwj:age=”22″
   cwj:university=”sjtu”
   cwj:city=”shanghai”
   />
大家可以看来下边包车型地铁八个属性,是我们自定义的。作为标准xml规范,可能还富含了接近
xmlns:android=”http://schemas.android.com/apk/res/**android**”  那样的说话,对于定义完整的View,我们的命名空间为cwj,那里能够写为
xmlns:cwj=http://schemas.android.com/apk/res/**cn.com.android123.cwjView** 或
xmlns:cwj=http://schemas.android.com/apk/res/**android** 都可以 
 对于定义的cwj命名空间和age、university以及city的七个属性大家什么样定义呢?
在工程的res/values目录中大家新建一个cwj_attr.xml文件,编码情势为utf-8是2个好习惯,内容如下
<?xml version=”1.0″ encoding=”utf-8″ ?>
<resources>
  <declare-styleable name=”CwjView”>
  <attr name=”age” format=”integer” />
  <attr name=”city” format=”string” />
  <attr name=”university” format=”string” />
  </declare-styleable>
</resources> 
 那里大家或然对format不是很通晓,方今Android系统内置的格式类型有integer比如ProgressBar的速度值,float比如RatingBar的值大概是3.5颗星,boolean比如ToggleButton的是否勾选,string比如TextView的text属性,当然除了我们广阔的功底项目外,Android的性质还有新鲜的例如color是用来颜色属性的,能够分辨为#FF0000等类别,当然还有dimension的尺码类型,比如23dip,15px,18sp的长短单位,还有一种独特的为reference,一般用来引用@+id/cwj
@drawable/xxx那样的花色。   当然哪天用reference呢?
大家就以定义三个颜色为例子,   <attr name=”red”
format=”color|reference”
/>  这里大家用了逻辑或的运算符,定义的革命是颜色类型的,同时能够被引述 
 当然,对于我们自定义的类中,大家必要动用二个名为obtainStyledAttributes的主意来获得大家的概念。在咱们自定义View的构造方法(Context
context, AttributeSet attrs)的重载类型中能够用   public
CwjView(Context context, AttributeSet attrs) {
  super(context, attrs);
        TypedArray a = context.obtainStyledAttributes(attrs,
          R.styleable.cwj_attr);
        mAge = a.getInteger(R.styleable.CwjView_age, 22);
        mCity = a.getString(R.styleable.CwjView_city, “shanghai”);
        mUniversity= a.getString(R.styleable.CwjView_university,
“sjtu”);
        a.recycle(); //Android123唤起大家不要忘了回收能源 }
这样类的大局成员变量
mAge、mCity就拿走了我们要求的始末,当然遵照layout中的数值大家自定义的CwjView必要动态的拍卖部分数量的场地,能够应用AttributeSet类的getAttributeResourceValue方法得到。
public CwjView(Context context, AttributeSet attrs)
{
  super(context, attrs);
  resId = attrs.getAttributeResourceValue(“cn.com.android123.CwjView”,
“age”, 100);  
  resId = attrs.getAttributeResourceValue(“cn.com.android123.CwjView”,
“city”, “shanghai”);
  //resID就足以轻易使用了
}
以上二种方法中,参数的末梢2个数值为暗中同意的,假设你有不清楚的地点能够来函到android123@163.com 我们会在第近年来间回复。

  1. 自定义Android宗旨风格theme.xml方法

在Android中能够通过自定义宗旨风格格局来促成天性化以及复用,首先大家创造theme.xml大旨文件,保存地方为工程的res/values/theme.xml
,那里我们得以能够为大旨起叁个名号,比如CWJ,那里去除了xml的文件头<?xml
version=”1.0″
encoding=”utf-8″?>那行,大家在工程中只需在androidmanifest.xml文件的Activity节点中投入android:theme=”@style/Theme.CWJ”
属性,则这一个Activity就动用了那种宗旨风格,整个xml的显要代码如下:
<resources>
    <style name=”Theme.CWJ” parent=”android:Theme”>
        <item
name=”android:windowBackground”>@drawable/android123</item>
    </style>
</resources> 
 个中地点的代码中,我们定义设置全局android:windowBackground即背景值为/res/drawable中的android123图片为背景,越多的性质定义可以参考view的layout
xml属性设置,比如大家设置有着字体颜色、大体大小和体裁,能够在style节点中参预 
 <item name=”android:textColor”>#fff</item>
  <item name=”android:textSize”>14sp</item>
  <item
name=”android:textStyle”>bold</item>  当然大家得以将地点的android123的图形创新下,使用二个xml文件替代,比如选拔bitmap对象,则/res/drawable/android123.xml的完全代码变为 
 <?xml version=”1.0″ encoding=”utf-8″?> <bitmap
xmlns:android=”http://schemas.android.com/apk/res/android
     android:src=”@drawable/cwj_image”
     android:tileMode=”repeat” />   
那里大家应用了3个bitmap对象来分析cwj_image图片,当然那里能够辨别各系列型的图形,当中android:tileMode是bitmap的中间属性,当中tileMode设置为repeat代表重复,那样可以节省bitmap能源,比如大家的背景是一层楼,那么全屏可以展现同一的为5层效益,而图片仅是一层大小,对于能源利用绝对更高。 
 当然bitmap的属性tileMode的值为repeat外还有任何的值比如clamp、mirror,那一个值并从未在SDK中并没有找到定义,通过上次Android开发网的 Android自定义View以及layout属性全攻略 一文,大家得以联想到bitmap属于android.graphics.Bitmap
包,由于是android框架,所以下载git的base包,找到此类,类的实例化时android123早已在 Android自定义View以及layout属性全攻略 说的很清楚,所以大家一定到res\values中找到attr.xml有关bitmap的概念即可,有关bitmap的更加多属性如  antialias、filter和dither都能够找到使用。

  1. android调节和测试工具monkey压力测试实战

洋洋Android开发者也许因为从没丰硕测试自个儿的软件导致很不难出现FC(Force
Close)的标题,那里我们得以经过利用Android固件中自带的monkey工具来做软件的压力测试,monkey工具得以一成不变各个按键,触屏,轨迹球、activity等事件,那里Android123唤起咱们不难monkey正是三个小猴子随机狂玩你的android软件,看看会不会产生至极。 
 具体的选拔大家因此Android
SDK给大家的adb调节和测试桥链接设备或模拟器,进入Linux
Shell状态,当然大家得以输入adb
shell获取装备的shell,也能够直接通过adb命令执行,比如说adb shell
monkey来查阅monkey工具中的参数表明,如图:  图片 4 
 大家要测试的apk文件要在android设备中一度安装,当然模拟器中也能够测试的。执行adb
shell monkey -p cn.com.android123.cwj -v 100
我们履行那句的中富含了p参数,那里表示已设置软件的packageName,而v代表查看monkey生成的详细随机事件名,最终的数字100为大家测试的即兴事件数量为100.关于越多的测试方法,请查看上海体育场所中的参数,整个测试相比不难单很得力,不要紧试试。

  1. 自定义View

至于Android的自定义View的框架明日大家一并座谈下,对于健康的玩乐,大家在View中供给处理以下二种难题:
1.说了算事件 2.刷新View 3. 制图View   1.
对于控制事件明天大家只处理按键事件onKeyDown,以往的篇章少校会讲到荧屏触控的切实处理onTouch伊夫nt以及Sensor重力感应等方法。 
 2. 刷新view的方法那里首要有invalidate(int l, int t, int r, int b)
刷新局地,三个参数分别为左、上、右、下。整个view刷新
invalidate(),刷新一个矩形区域 invalidate(Rect dirty)
,刷新2个特点Drawable, invalidateDrawable(Drawable drawable)
,执行invalidate类的法守门员会安装view为无效,最后致使onDraw方法被再一次调用。由于明天的view相比简单,Android123晋升大家只要在线程中刷新,除了选拔handler格局外,能够在Thread中央直机关接使用postInvalidate方法来促成。 
 3.
绘制View首假设onDraw()中经过形参canvas来拍卖,相关的绘图主要有drawRect、drawLine、drawPath等等。view方法内部还重写了成都百货上千接口,其回调方法能够接济我们看清出view的地方和大小,比如onMeasure(int,
int) Called to determine the size requirements for this view and all
of its children.  、onLayout(boolean, int, int, int, int) Called when
this view should assign a size and position to all of its children
和onSizeChanged(int, int, int, int) Called when the size of this view
has changed.
具体的职能,大家可以用Logcat获取当view变化时每一个形参的转移。 
 上面cwjView是我们为事后玩耍设计的二个简便自定义View框架,大家得以阅览在Android平台自定义view仍然很不难的,同时Java援助多一而再可以帮忙大家不停的圆满复杂的难题。
public class cwjView extends View {     public cwjView(Context
context) {
      super(context);
      setFocusable(true); //允许得到大旨
      setFocusableInTouchMode(true); //获取关节时允许触控
   }    @Override
   protected Parcelable onSaveInstanceState() {  //处理窗口保存事件
      Parcelable pSaved = super.onSaveInstanceState();
      Bundle bundle = new Bundle();
     //dosomething
      return bundle;
   }
   @Override
   protected void onRestoreInstanceState(Parcelable state)
{  //处理窗口还原事件
      Bundle bundle = (Bundle) state;      //dosomething
     super.onRestoreInstanceState(bundle.getParcelable(“cwj”));
      return;
   }
       @Override
   protected void onSizeChanged(int w, int h, int oldw, int oldh)
//处理窗口大小变化事件
   {
      super.onSizeChanged(w, h, oldw, oldh);
   }    @Override
   protected void onMeasure (int widthMeasureSpec, int
heightMeasureSpec)  
   {
      super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//若是不让父类处理记住调用setMeasuredDimension
   }
   @Override
   protected void onLayout (boolean changed, int left, int top, int
right, int bottom)
   {
    super.onLayout (changed,left,top, ight,bottom) ;
   }    @Override
   protected void onDraw(Canvas canvas) {
      Paint bg = new Paint();
      bg.setColor(Color.Red);
      canvas.drawRect(0, 0, getWidth()/2, getHeight()/2, bg);
//将view的左上角四分一填充为革命  
   }    @Override
   public boolean onTouchEvent(MotionEvent event) {
         return super.onTouch伊芙nt(event); //让父类处理荧屏触控事件
   }    @Override
   public boolean onKeyDown(int keyCode, Key伊夫nt event) {
//处理按键事件,响应的轨迹球事件为 public boolean onTrackball伊芙nt
(Motion伊芙nt event)
      switch (keyCode) {
      case KeyEvent.KEYCODE_DPAD_UP:
         break;
      case KeyEvent.KEYCODE_DPAD_DOWN:
         break;
      case KeyEvent.KEYCODE_DPAD_LEFT:
         break;
      case KeyEvent.KEYCODE_DPAD_RIGHT:
         break;
      case KeyEvent.KEYCODE_DPAD_CENTE奥迪Q5: //处理中键按下
         break;
      default:
         return super.onKeyDown(keyCode, event);
      }
      return true;
   } } 
 上边大家能够看来onMeasure使用的是父类的处理办法,假使我们须要化解自定义View的大大小小,能够尝尝下边包车型大巴办法 
  @Override
   protected void onMeasure (int widthMeasureSpec, int
heightMeasureSpec)  
   {
      height = View.MeasureSpec.getSize(heightMeasureSpec); 
      width = View.MeasureSpec.getSize(widthMeasureSpec); 
      setMeasuredDimension(width,height); 
 //那里面是原有的高低,须要重新总括能够修改本行      //dosomething   
}

  1. Canvas和Paint实例

前天大家在Android游戏开发之旅三
View详解中提到了onDraw方法,有关详细的落到实处大家后天重中之重说下Android的Canvas和Paint对象的运用实例。 
 Canvas类首要达成了荧屏的绘图进程,当中包蕴了许多实用的主意,比如绘制一条路子、区域、贴图、画点、画线、渲染文本,下边是Canvas类常用的章程,当然Android开发网提醒咱们多多主意有例外的重载版本,参数更灵活。 
 void drawRect(RectF rect, Paint paint)
//绘制区域,参数一为RectF二个区域   void drawPath(Path path, Paint
paint) //绘制3个路线,参数一为Path路径对象    void  drawBitmap(Bitmap
bitmap, Rect src, Rect dst, Paint paint) 
 //贴图,参数一正是我们健康的Bitmap对象,参数二是源区域(Android123唤起那里是bitmap),参数三是目的区域(应该在canvas的地点和分寸),参数四是Paint画刷对象,因为用到了缩放和拉伸的或是,当原始Rect不等于目的Rect时品质将会有急剧损失。 
  void  drawLine(float startX, float startY, float stopX, float stopY,
Paint
paint)  //画线,参数一开始点的x轴地点,参数二早先点的y轴地点,参数三终点的x轴水平地方,参数四y轴垂直地点,最终贰个参数为Paint画刷对象。 
 void  drawPoint(float x, float y, Paint paint)
//画点,参数一水准x轴,参数二垂直y轴,第陆个参数为Paint对象。
  void drawText(String text, float x, float y, Paint
paint)  //渲染文本,Canvas类除此而外上边的还是能描绘文字,参数一是String类型的公文,参数二x轴,参数三y轴,参数四是Paint对象。 
 void  drawTextOnPath(String text, Path path, float hOffset, float
vOffset, Paint paint)
//在路线上制图像和文字本,相对于地点第二个参数是Path路径对象 
 从地点来看大家得以见到Canvas绘制类比较简单同时很灵巧,完毕一般的办法一般没有失常态,同时能够附加的拍卖规划出一部分功效,可是细心的网上朋友可能发现最后一个参数均为Paint对象。假诺大家把Canvas当做绘美学家来看,那么Paint正是我们描绘的工具,比如画笔、画刷、颜料等等。 
 Paint类常用方法: void  setALANDGB(int a, int r, int g, int
b)  设置Paint对象颜色,参数一为阿尔法透明通道
void  setAlpha(int a)  设置阿尔法不光滑度,范围为0~255
void  setAntiAlias(boolean aa)  //是不是抗锯齿 void  setColor(int
color)  //设置颜色,那里Android内部定义的有Color类包涵了有的大规模颜色定义
.
void  setFakeBoldText(boolean fakeBoldText)  //设置伪粗体文本
void  setLinearText(boolean linearText)  //设置线性文本
PathEffect  setPathEffect(PathEffect effect)  //设置路径效果
Rasterizer  setRasterizer(Rasterizer rasterizer) //设置光栅化
Shader  setShader(Shader
shader)  //设置阴影  void  setTextAlign(Paint.Align
align)  //设置文本对齐
void  setTextScaleX(float scaleX)  //设置文本缩放倍数,1.0f为原本
void  setTextSize(float textSize)  //设置字体大小
Typeface  setTypeface(Typeface
typeface)  //设置字体,Typeface包涵了字体的花色,粗细,还有倾斜、颜色等。
void  setUnderlineText(boolean underlineText)  //设置下划线
说到底Canvas和Paint在onDraw中央直机关接选取 @Override
   protected void onDraw(Canvas canvas) {     Paint paintRed=new
Paint();     paintRed.setColor(Color.Red); 
   canvas.drawPoint(11,3,paintRed); //在坐标11,3上画贰个红点
  } 
 下2回Android123将会具体讲到强大的帕特h路径,和字体Typeface相关的使用。

  1. View类详解

在Android游戏开发之旅二中大家讲到了View和SurfaceView的差别,明天Android123从View类开首重点的介绍Android图形展现基类的连锁方法和注意点。 
 自定义View的常用方法: onFinishInflate()
当View中装有的子控件均被映射成xml后触发 onMeasure(int, int)
明确全部子成分的深浅 onLayout(boolean, int, int, int, int)
当View分配全数的子成分的轻重和职务时触发 onSizeChanged(int, int, int,
int) 当view的高低发生变化时触发 onDraw(Canvas) view渲染内容的底细
onKeyDown(int, Key伊夫nt) 有按键按下后触发 onKeyUp(int, Key伊芙nt)
有按键按下后弹起时触发 onTrackball伊夫nt(Motion伊夫nt) 轨迹球事件
onTouch伊夫nt(Motion伊芙nt) 触屏事件 onFocusChanged(boolean, int, Rect)
当View获取或失去核心时触发  onWindowFocusChanged(boolean)
当窗口包罗的view获取或失去宗旨时触发 onAttachedToWindow()
当view被附着到3个窗口时触发 onDetachedFromWindow()
当view离开附着的窗口时接触,Android123唤起该方法和  onAttachedToWindow()
是倒转的。 onWindowVisibilityChanged(int)
当窗口中隐含的可知的view发生变化时触发 
 以上是View完毕的一对着力接口的回调方法,一般大家必要处理画布的展现时,重写onDraw(Canvas)用的的是最多的: 
 @Override
   protected void onDraw(Canvas canvas) {
   
//那里大家一贯使用canvas对象处理当下的画布,比如说使用Paint来摘取要填写的颜色 
  Paint paintBackground = new Paint();
 
 paintBackground.setColor(getResources().getColor(Odyssey.color.xxx));  //从Res中找到名为xxx的color颜色定义
   canvas.drawRect(0, 0, getWidth(), getHeight(), paintBackground);
//设置当前画布的背景颜色为paintBackground中定义的颜色,以0,0作为为起源,以近年来画布的肥瘦和冲天为第1即整块画布来填充。 
  
 具体的请查看Android123前途讲到的Canvas和Paint,在Canvas中大家得以兑现画路径,图形,区域,线。而Paint作为绘画艺术的对象足以设置颜色,大小,甚至字体的门类等等。
}
当然还有就是处理窗口还原状态难点(一般用来横竖屏切换),除了在Activity中能够调用外,开发娱乐时大家尽量在View中运用类似
@Override
   protected Parcelable onSaveInstanceState() {
      Parcelable p = super.onSaveInstanceState();
      Bundle bundle = new Bundle();
      bundle.putInt(“x”, pX);
      bundle.putInt(“y”, pY);
      bundle.putParcelable(“android123_state”, p);
      return bundle;
   }
   @Override
   protected void onRestoreInstanceState(Parcelable state) { 
      Bundle bundle = (Bundle) state;
      dosomething(bundle.getInt(“x”), bundle.getInt(“y”));
//获取刚才存款和储蓄的x和y消息
    
 super.onRestoreInstanceState(bundle.getParcelable(“android123_state”));
      return;
   } 
 在View中一经急需强制调用绘制方法onDraw,能够应用invalidate()方法,它有不少重载版本,同时在线程中的postInvailidate()方法将在Android游戏开发之旅六中的
自定义View完整篇讲到。

  1. View和SurfaceView

在Android游戏在这之中充当主要的不外乎决定类外正是显示类,在J2ME中我们用Display和Canvas来贯彻那几个,而GoogleAndroid中关系到体现的为view类,Android游戏开发中比较根本和复杂性的正是呈现和玩耍逻辑的处理。那里我们说下android.view.View和android.view.SurfaceView。SurfaceView是从View基类中派生出来的展现类,直接子类有GLSurfaceView和VideoView,能够观望GL和摄像播放以及Camera摄像头一般均运用SurfaceView,到底有哪些优势呢?
SurfaceView能够控制表面的格式,比如大小,显示在显示器中的地方,最根本是的提供了SurfaceHolder类,使用getHolder方法获取,相关的有Canvas  lockCanvas() 
Canvas  lockCanvas(Rect
dirty)  、void  removeCallback(SurfaceHolder.Callback
callback)、void  unlockCanvasAndPost(Canvas canvas)
控制图形以及绘制,而在SurfaceHolder.Callback
接口回调中得以因而上边四个抽象类能够协调定义具体的完成,比如第3个更改格式和出示画面。
abstract void  GALAXY TabChanged(SurfaceHolder holder, int format, int
width, int height)
abstract void  surfaceCreated(SurfaceHolder holder)
abstract void  surfaceDestroyed(SurfaceHolder holder)
  对于Surface相关的,Android底层还提供了GPU加速成效,所以一般实时性很强的使用中一言九鼎利用SurfaceView而不是一向从View创设,同时Android123前途背后说到的OpenGL中的GLSurfaceView也是从该类达成。 

  1. Android程序内部存款和储蓄器管理必读

诸多开发者都以从J2ME或J2EE上回复的,对于内部存款和储蓄器的行使和清楚并不是很到位,Android开发网本次给我们有个别架构上的指引,防止出现豆腐渣工程的产出。Android作为以Java语言为主的智能平台对于我们付出一些高品质和品质的软件以来精晓Android程序内部存款和储蓄器管理机制是必须的。
Android的Dalvik VM在基础方面和Sun
JVM没有啥样大的差距仅仅是字节码的优化,大家要明了如曾几何时候用gc哪天用recycle以及到底用不用finalization,因为Java对内部存款和储蓄器的分配只供给new开发者不需求体现的释放内部存款和储蓄器,可是那样造成的内部存款和储蓄器走漏难题的可能率反倒更高。 
 1.对刘震云规开发者而言要求明白Java的多样引用形式,比如强引用,软引用,弱引用以及虚引用。一些繁杂些的次第在漫长运营很恐怕出现就好像OutOfMemoryError的可怜。
2.并不要过多的愿意gc,不用的对象足以展现的装置为空,比如obj=null,那里Android123唤起大家,java的gc使用的是3个有向图,判断三个对象是或不是可行看的是其余的目的能抵达那几个目的的极端,有向图的相对于链表、二叉树来说费用是总而言之。
3.Android为每种程序分配的对内部存储器能够经过Runtime类的totalMemory()
freeMemory()
多个艺术得到VM的一些内部存储器音讯,对于系统heap内部存款和储蓄器获取,能够通过Dalvik.VMRuntime类的get迷你mumHeapSize()
方法取得最小可用堆内部存款和储蓄器,同时呈现释放软引用能够调用该类的gcSoftReferences()
方法,获取更加多的周转内部存款和储蓄器。
4.对此四线程的处理,假设出现的线程很多,同时有频仍的创办和自由,能够经过concurrent类的线程池解决线程创制的频率瓶颈。

  1. 永不在循环中创制过多的地头变量。
    有关Android和Java的系统性子分析,Android123将在之后的篇章中详尽描述怎么着调节和测试Java分析内部存款和储蓄器败露以及Android上的gdb调节和测试器分析得出内部存款和储蓄器品质立异。
  1. Android中内嵌字体完结本性化

在Android中我们的使用能够灵活的内嵌自个儿的字体文件,实现种种手提式有线电话机上能够正常的来得性格化文字,我们都知情TextView的setTypeface方法能够设置目的文字的展现性格,比如字体、颜色、粗体、斜体等。大家一贯找一个TrueTypeFont的字体文件即.ttf,对于Win32系统的用户能够一贯在Windows/fonts文件夹中能找到很多。比如微软雅黑就正确,然则体量太大,由于Android的Assets类有单个文件1MB容量的范围,大家先找个英文字体做测试。那里咱们将字体文件android123.ttf放到工程的assets文件夹的fonts目录中。 
    Typeface tf = Typeface.createFromAsset(getAssets(),
“fonts/android123.ttf”);   
     TextView tv = (TextView)findViewById(R.id.text);          
 tv.setTypeface(tf);    //设置TextView的风格
        tv.setText(“CWJ Test”);  
        tv.setTextSize(12); 
        tv.setTextColor(Color.RED);

  1. 得到和装置ListView的选择项

收获当前当选项  int curPos = listView.getFirstVisiblePosition();
当然是用getItemAtPosition(int nPos)方法也得以 ,设置当前选拔地点listView.setSelectedPosition(lastPos);  对于基于AbsListView为基类的ListView等控件均能够应用那种方式。

  1. android.text.format文件大小和日期解析类

很多网络朋友或然直接将团结的J2ME项目生硬的移植到Android平台,其实谷歌为大家提供好了文件大小和岁月日期解析类,它坐落android.text.format那一个包中,它提供了强有力的准绳解析方法: 
 1. IP地址解析类 在android.text.format.Formatter中提供了String
formatIpAddress(int addr)
这些主意可以轻松方便的将socket中的int型转成类似127.0.0.1的IP格式,供给小心的是Linux平台的字节顺序,即小字节序、低字节序little-endian。 
 2. 文件大小解析类
细心的网上朋友恐怕还观察了android.text.format.Formatter中的formatFileSize方法,该方法String
formatFileSize (Context context, long number)
,第③个参数是long型,一般为File对象的结尾修改时间或创办时间的方法,最终回到类似
12KB、5Bytes的值,20MB的字符串。   3. 日期时间分析类
,该类位于android.text.format.DateFormat那么些package中,该类提供了Java中的两种时光对象,Android123晋升大家下边二种格局为静态能够一向调用,如下: 
 final static CharSequence  format(CharSequence inFormat, Date
inDate)  //传入Date对象
  Given a format string and a Date object, returns a CharSequence
containing the requested date. final static
CharSequence  format(CharSequence inFormat, Calendar
inDate)  //Calendar对象
Given a format string and a Calendar object, returns a CharSequence
containing the requested date. final static
CharSequence  format(CharSequence inFormat, long
inTimeInMillis)  //long对象
Given a format string and a time in milliseconds since Jan 1, 1968丙胺搏来霉素T, returns a CharSequence containing the requested date. 
 我们可能看到了第3个参数均为inFormat那是3个CharSequence接口的String类型,它提供了灵活的年月格式解析字符串描述,Android开发网提示我们注意分寸写要区分,如 
  April 6, 1969 at 3:23am
例证,那么inFormat参数的写法和最后实施的结果如下对照,上面就以Android123的CWJ生日为例子如下
“MM/dd/yy h:mmaa” -> “11/03/87 11:23am”
“MMM dd, yyyy h:mmaa” -> “Nov 3, 1987 11:23am”
“MMMM dd, yyyy h:mmaa” -> “November  3, 1987 11:23am”
“E, MMMM dd, yyyy h:mmaa” -> “Tues, November 3, 1987 11:23am”
“EEEE, MMMM dd, yyyy h:mmaa” -> “Tuesday, Nov 3, 一九九〇 11:23am” 
 对于判断一个小时是否为24时辰制式能够经过android.text.format.DateFormat类的static
boolean  is24HourFormat(Context context)方法来判断。

  1. Android代码质量优化技术

现阶段以来Android
2.2的JIT性能有了实质的加强,可是对于老版本的次序升高Java执行效能还有好多语言特点来说,前几日Android123关乎的不是语法糖,而是基础的题材,对于Java
1.5之后将会有鲜明的改良。下边包车型大巴例子来自SDK: static class Foo {
        int mSplat;
    }
    Foo[] mArray =
… 
上边的静态类Foo的履行效劳和属性,大家分多个方法zero、one和two来做比较。
    public void zero() {  //超越1/四个人唯恐不难直接那样写
        int sum = 0;
        for (int i = 0; i < mArray.length; ++i) {
            sum += mArray.mSplat;
        }
    }
    public void one() { //通过本地对象立异质量
        int sum = 0;
        Foo[] localArray = mArray;
        int len = localArray.length;
        for (int i = 0; i < len; ++i) {
            sum += localArray
.mSplat;
        }
    }
    public void two() { //推荐的措施,通过Java
1.5的新语法本性能够急戏改正质量
        int sum = 0;
        for (Foo a : mArray) {
            sum += a.mSplat;
        } 
    } zero() is slowest, because the JIT can’t yet optimize away
the cost of getting the array length once for every iteration through
the loop. one() is faster. It pulls everything out into local
variables, avoiding the lookups. Only the array length offers a
performance benefit. two() is fastest for devices without a JIT,
and indistinguishable from one() for devices with a JIT. It uses
the enhanced for loop syntax introduced in version 1.5 of the Java
programming language.
**

  1. Android开发注意点 Part One

Android已经的无数细节难点大家由此平台支付总括不断完善那么些列表,如若你有有关的情节能够联系android123@163.com . 
  ① 、AssetManager –
已知单个文件处理不可能超越1MB,所以一旦财富非常大,提议接纳Zip格式压缩存放。 
  二 、ScrollView中嵌入ListView –
这么些作法大概会出现你的ListView仅仅展现1行半。   
三 、Android自带的Zip处理类对文本名编码不能够辨别,也远非提供显示的安装形式,在zlib中写死了。 
  四 、使用部分财富对象记住关闭,比如对于文件流对象最后       
   FileOutputStream os = xxx;            try {
                //dosomething
            } finally {
                os.close();  //展现的选择finally关闭文件对象。
            }       
   对于Cursor而言,在移动地点时首先判断Cursor是还是不是为空,最后利用完仍旧需求close方法,尽管采用,能够动用deactivate方法释放当前财富,通过requery方法重复询问。 
 五 、SDK中标记为 deprecated
字样的,常规状态下是有更好的点子能够代表,短时间内足以放心使用。那些艺术一般高版本的SDK都能够进步包容,最近一向不意识Android废弃某个API的支持。 
 ⑥ 、Notification的Intent不恐怕传递到对象的Activity,Service和Broardcast没有测试过,中途必要通过PendingIntent,或许那边出现了难点。

  1. Android上HTTP协议通信状态获得

经常状态下轻量级的Http传输Android平台能够一贯使用Sun
Java的HttpUSportageLConnection类方法处理,比假设协调定义二回呼吁header可以经过setRequestProperty设置,而大家供给得到的Http
Web Server状态能够透过HttpU哈弗LConnection.getResponseCode()
的点子赢得。   当然Http协议重临值常见的有 200
为成功,400为呼吁错误,404为未找到,500为服务器内部错误,403无权查看,302为重定向等等。 
 对于Android平台提供更周详的Apache类有HttpClient
、HttpPost、HttpResponse、HttpGet和HttpEntity,个中对于数据报头header构造通过HttpEntity,而回到状态值能够经过HttpResponse获取。 
 有关Android客户端和Server通信类相关的开销咱们将会在其后小说中做大批量实例介绍。

  1. Android布局Java代码构造法

貌似情状下对于Android程序布局我们一再选择XML文件来编排,那样能够增加开支功效,可是考虑到代码的安全性以及履行成效,能够通过Java代码执行创设,固然Android编写翻译过的xml是二进制的,不过加载xml解析器的频率对于财富占用依然比较大的,一般贰个简易的TextView,比如 
   <TextView
    android:id=”@+id/textControl “
    android:layout_width=”100px”
    android:layout_height=”wrap_content” />   
能够等价于下边包车型客车Java代码:    LinearLayout.LayoutParams textParams =
new LinearLayout.LayoutParams(100, LayoutParams.WRAP_CONTENT);
//宽度为100px,高为自适应最小的可观    // setOrientation(VE汉兰达TICAL);
设置布局为垂直    TextView textControl = new
TextView(this);//要是从1个XXXLayout.,比如LinearLayout为View的基类时这里this应该换来为创设改类的Context
   textControl.setText(“Android开发网欢迎您”);
   addView( textControl, textParams );   
当然Java处理功用比XML快得多,但是对于三个繁杂界面包车型大巴编写,或者须求一些套嵌考虑,假如你考虑灵活的话,使用Java代码来布局你的Android应用程序是多个更好的不二法门。

  1. 测试Android软件质量重要情势

对于Android平台上软件的性质测试能够经过以下三种办法来分析功用瓶颈,近来谷歌(Google)在Android软件开发进程中早已引入了四种测试工具包,比如Unit测试工程,调节和测试类,还有模拟器的Dev
Tools都足以直接反应执行质量。    1. 在模拟器上的Dev
Tools能够激活荧屏展现当前的FPS,CPU使用率,能够援救我们测试一些3D图形界面的个性。 
 
2.  一般涉及到网络使用的次序,在效能上和网速有不少提到,那里须要反复的调节才能实际掌握。 
  3.
对此逻辑算法的效能执行,大家选择Android上最广泛的,总结执行时间来查阅: 
     long start = System.currentTimeMillis();
      //android开发网提示那里抓牢在的拍卖do something
      long duration = System.currentTimeMillis() – start;      
最终duration保存着其实处理该办法供给的毫秒数。这里就像Win32上的GetTickCount,在Win
32和Symbian上都提供了高精度的习性计数器和低阶计时器,那里在Dalvik
VM上的Java层那种措施对于一般的运用能够。    4.
GC功能跟踪,若是你执行的行使比较简单,能够在DDMS中查阅下Logcat的VM释放内部存款和储蓄器情形,大概模拟下那么些地点能够缓存数据或立异算法的。 
  5.
线程的应用和协同,Android平台上给我们提供了增进的多职务同步方法,但在深层上并不曾过多的比如说自旋锁等高级应用,不过对于Service和appWidget而言,他们其实的出品中都应当以二十八线程的章程处理,以释放CPU时间,对于线程和堆内部存款和储蓄器的查阅这么些都足以在DDMS中看看。 
  更加多的调剂和总体性测试方法Android123将在后头的内容中冒出。

  1. Splash Screen开场屏在Android中的达成

多多网上朋友恐怕发现以来Tencent推出的无绳话机QQ
Android版包括了二个开场屏Splash
Screen载入效果,平时游戏或大型软件打开时可能需求三个刑释解析财富的进度,需求1个前台的动画播放和后台的逻辑处理线程同盟,当然对于简易的软件也足以加3个Splash
Screen作为美化。在Android平台上怎么样完成吗? 
 首先成立一个Activirty,在SetContentView时径直通过ImageView创制贰个全屏的图纸,Android123提示大家还要考虑好分辨率和当下设备一致,onCreate添加代码如下: 
 new Handler().postDelayed(new Runnable(){   //
为了削减代码应用匿名Handler创制四个延时的调用
            public void run() {  
                Intent i = new Intent(SplashScreen.this, Main.class); 
  //通过Intent打开最后真正的主界面Main那些Activity
                SplashScreen.this.startActivity(i);   
//启动Main界面
                SplashScreen.this.finish();    //关闭本人那一个开场屏
            }  
        }, 五千);   //5秒,够用了吗

  1. Android的Activity你知多少呢?

见到那些标题很多网上朋友肯定答应,小编驾驭Activity是Android上的窗口基类,理解Activity的生命周期比如onCreate
onStop等,呵呵,依照那样说Android123还清楚Activity的达成其实是从ApplicationContext,而ApplicationContext是从Context这么些抽象类派生而来的,当然大家看看显示的是View恐怕ViewGroup,当然今日说的不是这么些东西,而是很多网上好友来问的Android为何不规划三个职务管理器,当然从Android
1.5始发ActivityManager类提供了restartPackage可以关闭八个顺序,需求加上<uses-permission
android:name=”android.permission.RESTA奥迪Q5T_PACKAGES”/>那一个权力,然而我们注意到,长按Home键可以看到从前程序的运转,同时能够长足的切换回来。那便是Android独有的先后生命周期管理机制
Activity历史栈。 
 大家在三个司空眼惯的主次主窗口A中打开了一个窗口B,而窗口B打开了窗口C,不过按下Back键后结果大于了预期,是的那正是Activity的history
stack的因由,在数据结构中栈是FIFO的,阻止大家不乐意看的情事的发生则能够在开拓新Activity时拉长标记FLAG_ACTIVITY_NO_HISTO奥迪Q3Y,代码如下: 
   Intent i= new Intent(this, cwj.class);  
    i.setFlags(Intent.FLAG_ACTIVITY_NO_HISTO奥迪Q5Y); 
 //Android开发网提示我们相关的还有Intent.FLAG_ACTIVITY_CLEAR_TOP,都试试
    startActivity(i);   
当然越多的程序Activity控制可以再androidmanifest.xml中定义。

  1. JSONObject在Android上的选取

假定你过去开发过AJAX应用,相信对JSONObject不会素不相识吧,作为基于JavaScript的数据沟通格式,能够直接代替Xml,那里Android从1.0伊始就全盘扶助JSONObject。在平日利用中央直属机关接引入import
org.json.JSONObject;即可方便使用。当然同类的还有SOAP。 
 在例行使用方便JSONObject对象足以兑现类似Bundle或Parcel能够封装数据,代替叁个XML的ITEM,但最大的优势是足以实施一些简约的措施,比如说getString、has、put、getBoolean、getInt等数据类型的存取操作。Android123提醒我们对此健康的档次开发,后天本文不考虑Server端的布局,在Android平台上处理那么些比较简单,主假若一对http的央求处理。能够一贯引入import
org.apache.http.xxx来贯彻web
server层的数据调换,假诺你没有正规的Server开发技术,能够透过简单的Web合营JSON方式非常快达成和谐的交互式应用。

  1. Android高质量文件类MemoryFile

多如牛毛网上朋友抱怨Android处理底层I/O质量不是很完美,要是不想使用NDK则能够通过MemoryFile类达成高品质的文书读写操作。MemoryFile顾名思义就是内部存款和储蓄器文件的情致,如若你过去转业过Win32支出,那么它的法则正是MapViewOfFile(),当然付出过Linux的网上朋友恐怕神速就联想到了mmap(),是的此类就是她们的托管代码层封装,位于android.os.MemoryFile这些岗位,从Android
1.0开首就被支持。   MemoryFile适用于哪些地方呢? 
 对于I/O需求频仍操作的,紧倘若和外部存款和储蓄相关的I/O操作,MemoryFile通过将
NAND或CF闪存卡上的文本,分段映射到内部存款和储蓄器中实行改动处理,那样就用高速的RAM代替了ROM或SDXC卡,品质自然增进不少,对于Android手提式有线电电话机而言同时还减少了电量消耗。Android123升迁网络好友该类达成的功用不是诸多,直接从Object上接轨,通过JNI的章程直接在C底层执行。
首要的构造方法 MemoryFile(String name, int length)
,那里第②个参数为文件大小,须要证实的是Android的MemoryFile和守旧的mmap还有一丝丝组别,终究是手机,它里面包车型地铁内部存储器管理方法ashmem会从根本中回收财富。究竟如今有个别低端机型的RAM也正如吃紧。  synchronized
boolean  allowPurging(boolean
allowPurging)  //允许ashmem清理内部存储器,线程安全共同的办法。
void  close()
//关闭,因为在Linux内部mmap占用一个句柄,不用时必然要释放了
InputStream  getInputStream()  重返读取的内容用Java层的InputStream保存
OutputStream  getOutputStream()  把一个OutputSream写入到MemoryFile中
boolean  isPurgingAllowed() //判断是或不是允许清理
int  length()  //重临内部存款和储蓄器映射文件大小
下边就是大家耳熟能详的,读写细节,主要是对字符数组的操作,那里大家要总括好每一个文件类型的占据,同时考虑到效能对于自身分配的轻重缓急考虑粒度对齐。
int  readBytes(byte[] buffer, int srcOffset, int destOffset, int
count)
void  writeBytes(byte[] buffer, int srcOffset, int destOffset, int
count)     具体的其实使用,Android开发网将在下次和豪门讲到。

  1. TextUtils类-Android字符串处理类

对于字符串处理Android为大家提供了三个大约实用的TextUtils类,倘使拍卖比较不难的始末不用去思考正则表明式无妨试试这么些在android.text.TextUtils的类,主要的职能如下: 
 是或不是为空字符 static boolean  isEmpty(CharSequence
str)  拆分字符串  public static String[] split (String text, String
expression) ,Android开发网提醒我们仔细看例子如下 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”, “”}. 拆分字符串使用正则 public
static String[] split (String text, Pattern pattern) 
 鲜明大小写是不是可行在当前地方的文本TextUtils.getCapsMode(CharSequence
cs, int off, int reqModes)   使用HTML编码那个字符串  static
String  TextUtils.htmlEncode(String s)   

  1. InputSream输入流转String字符串,Android开发工具类

在Android平台上使用Java层处理I/O时第2运用流,这里Android开发网给大家四个福利的类,能够处理InputStream输入流转为String字符串,在成效上,大家使用了字符串拼接StringBuilder类缩小内部存款和储蓄器碎片以及BefferedReader类实现2个缓存。 
   private String Stream2String(InputStream is) {
            BufferedReader reader = new BufferedReader(new
InputStreamReader(is), 16*1024);
//强制缓存大小为16KB,一般Java类私下认可为8KB
            StringBuilder sb = new StringBuilder();
            String line = null;
            try {
                while ((line = reader.readLine()) != null)
{  //处理换行符
                    sb.append(line + “\n”); 
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return sb.toString();
        }     }

  1. layout资源蕴藏,android开发必读

神蹟大家在一个Android程序中只怕会复用布局文件,那时能够在贰个xml文件中复用过去的布局文件,不过和健康的利用差异的是,要求丰硕类似包蕴头文件一律的include关键字,比如下边大家须求包含layout文件夹下的view.xml布局文件,需求<include
layout=”@layout/view” />  那样下,完整的如下,大家能够试一试。
<?xml version=”1.0″ encoding=”utf-8″?>  
<LinearLayout
xmlns:android=”http://schemas.android.com/apk/res/android” 
    android:orientation=”vertical” 
    android:layout_width=”fill_parent” 
    android:layout_height=”fill_parent” 
    >  
<TextView    
    android:layout_width=”wrap_content”   
    android:layout_height=”wrap_content”   
    android:text=”@string/cwj” 
    />
<include layout=”@layout/view” /> 
<include android:id=”@+id/block” layout=”@layout/item” /> 
 <TextView    
    android:layout_width=”wrap_content”   
    android:layout_height=”wrap_content”   
    android:text=”@string/android123″ 
    />  
</LinearLayout> 

48.Android控件开发之ToggleButton原理

在Android平台上相比有特色的正是ToggleButton控件,固然它的功能和CheckBox有个别接近,不过她们的用处如故有肯定的分别比如ToggleButton原本有图表装饰,通过ToggleButton能够很领会的显示某些状态。它们均从Button为基类的CompoundButton中完结,其真伪事件从Checkable来完结。 
 public abstract
class CompoundButton extends Button implements Checkable {
    private boolean mChecked; //状态是还是不是选中
    private int mButtonResource;
    private boolean mBroadcasting;
    private Drawable mButtonDrawable; //按钮的图标
    private OnCheckedChangeListener mOnCheckedChangeListener;
//选中状态改变监听
    private OnCheckedChangeListener mOnCheckedChangeWidgetListener; 
   private static final int[] CHECKED_STATE_SET = {
        R.attr.state_checked
    };     public CompoundButton(Context context) {
        this(context, null);
    }     public CompoundButton(Context context, AttributeSet attrs)
{
        this(context, attrs, 0);
    }     public CompoundButton(Context context, AttributeSet attrs,
int defStyle) {
        super(context, attrs, defStyle);         TypedArray a =
                context.obtainStyledAttributes(
                        attrs,
com.android.internal.R.styleable.CompoundButton, defStyle, 0);       
 Drawable d =
a.getDrawable(com.android.internal.R.styleable.CompoundButton_button); 
        if (d != null) {
            setButtonDrawable(d);
        }         boolean checked = a
               
.getBoolean(com.android.internal.R.styleable.CompoundButton_checked,
false);
        setChecked(checked);         a.recycle(); //显式的GC
    }     public void toggle() {
        setChecked(!mChecked);
    }     @Override
    public boolean performClick() {
              toggle();
        return super.performClick();
    }     public boolean isChecked() {
        return mChecked;
    }     public void setChecked(boolean checked) {
        if (mChecked != checked) {
            mChecked = checked;
            refreshDrawableState(); //更新当前情状的按钮图标          
  if (mBroadcasting) {
                return;
            }             mBroadcasting = true;
            if (mOnCheckedChangeListener != null) {
                mOnCheckedChangeListener.onCheckedChanged(this,
mChecked);
            }
            if (mOnCheckedChangeWidgetListener != null) {
                mOnCheckedChangeWidgetListener.onCheckedChanged(this,
mChecked);
            }             mBroadcasting = false;           
        }
    }     public void
setOnCheckedChangeListener(OnCheckedChangeListener listener) {
        mOnCheckedChangeListener = listener;
    }     void
setOnCheckedChangeWidgetListener(OnCheckedChangeListener listener) {
        mOnCheckedChangeWidgetListener = listener;
    }     public static interface OnCheckedChangeListener {
        void onCheckedChanged(CompoundButton buttonView, boolean
isChecked);
    }      public void setButtonDrawable(int resid) {
        if (resid != 0 && resid == mButtonResource) {
            return;
        }         mButtonResource = resid;         Drawable d =
null;
        if (mButtonResource != 0) {
            d = getResources().getDrawable(mButtonResource);
        }
        setButtonDrawable(d);
    }     public void setButtonDrawable(Drawable d) {
        if (d != null) {
            if (mButtonDrawable != null) {
                mButtonDrawable.setCallback(null);
                unscheduleDrawable(mButtonDrawable);
            }
            d.setCallback(this);
            d.setState(getDrawableState());
            d.setVisible(getVisibility() == VISIBLE, false);
            mButtonDrawable = d;
            mButtonDrawable.setState(null);
            setMinHeight(mButtonDrawable.getIntrinsicHeight());
        }         refreshDrawableState();
    }     @Override
    public boolean
dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
        boolean populated =
super.dispatchPopulateAccessibilityEvent(event);         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);
        }         return populated;
    }     @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);         final Drawable buttonDrawable =
mButtonDrawable;
        if (buttonDrawable != null) {
            final int verticalGravity = getGravity() &
Gravity.VERTICAL_GRAVITY_MASK;
            final int height = buttonDrawable.getIntrinsicHeight(); 
           int y = 0;             switch (verticalGravity) {
                case Gravity.BOTTOM:
                    y = getHeight() – height;
                    break;
                case Gravity.CENTER_VERTICAL:
                    y = (getHeight() – height) / 2;
                    break;
            }             buttonDrawable.setBounds(0, y,
buttonDrawable.getIntrinsicWidth(), y + height);
            buttonDrawable.draw(canvas);
        }
    }     @Override
    protected int[] onCreateDrawableState(int extraSpace) {
        final int[] drawableState =
super.onCreateDrawableState(extraSpace + 1);
        if (isChecked()) {
            mergeDrawableStates(drawableState, CHECKED_STATE_SET);
        }
        return drawableState;
    }     @Override
    protected void drawableStateChanged() {
//android123提示状态改变时索要转移按钮的图标
        super.drawableStateChanged();
        if (mButtonDrawable != null) {
            int[] myDrawableState = getDrawableState();
            mButtonDrawable.setState(myDrawableState);
            invalidate();
        }
    }     @Override
    protected boolean verifyDrawable(Drawable who) {
        return super.verifyDrawable(who) || who == mButtonDrawable;
    }     static class SavedState extends BaseSavedState {
        boolean checked;              SavedState(Parcelable
superState) {
            super(superState);
        }
        private SavedState(Parcel in) {
            super(in);
            checked = (Boolean)in.readValue(null);
        }         @Override
        public void writeToParcel(Parcel out, int flags) {
            super.writeToParcel(out, flags);
            out.writeValue(checked);
        }         @Override
        public String toString() {
            return “CompoundButton.SavedState{“
                    +
Integer.toHexString(System.identityHashCode(this))
                    + ” checked=” + checked + “}”;
        }         public static final
Parcelable.Creator<SavedState> CREATOR
                = new Parcelable.Creator<SavedState>() {
            public SavedState createFromParcel(Parcel in) {
                return new SavedState(in);
            }             public SavedState[] newArray(int size) {
                return new SavedState[size];
            }
        };
    }     @Override
    public Parcelable onSaveInstanceState() {
        // Force our ancestor class to save its state
        setFreezesText(true);
        Parcelable superState = super.onSaveInstanceState();       
 SavedState ss = new SavedState(superState);         ss.checked =
isChecked();
        return ss;
    }     @Override
    public void onRestoreInstanceState(Parcelable state) {
        SavedState ss = (SavedState) state;
        super.onRestoreInstanceState(ss.getSuperState());
        setChecked(ss.checked);
        requestLayout();
    }
}
从上边来看大家了然CompuundButton的落到实处绝对繁琐了些,首若是考虑气象是否已经入选等情景的新闻布告,Android开发网提示我们而ToggleButton相对CompuundButton增加的给用户而言首要性是开关的文字显示。
public class ToggleButton extends CompoundButton {
    private CharSequence mTextOn;
    private CharSequence mTextOff;
    private Drawable mIndicatorDrawable;     private static final int
NO_ALPHA = 0xFF;
    private float mDisabledAlpha;
    public ToggleButton(Context context, AttributeSet attrs, int
defStyle) {
        super(context, attrs, defStyle);
        TypedArray a =
            context.obtainStyledAttributes(
                    attrs,
com.android.internal.R.styleable.ToggleButton, defStyle, 0);
        mTextOn =
a.getText(com.android.internal.R.styleable.ToggleButton_textOn);
        mTextOff =
a.getText(com.android.internal.R.styleable.ToggleButton_textOff);
        mDisabledAlpha =
a.getFloat(com.android.internal.R.styleable.ToggleButton_disabledAlpha,
0.5f);
        syncTextState();
        a.recycle();
    }     public ToggleButton(Context context, AttributeSet attrs) {
        this(context, attrs,
com.android.internal.R.attr.buttonStyleToggle);
    }     public ToggleButton(Context context) {
        this(context, null);
    }     @Override
    public void setChecked(boolean checked) {
        super.setChecked(checked);
        syncTextState();
    }     private void syncTextState() {
        boolean checked = isChecked();
        if (checked && mTextOn != null) {
            setText(mTextOn);
        } else if (!checked && mTextOff != null) {
            setText(mTextOff);
        }
    }     public CharSequence getTextOn() {
        return mTextOn;
    }     public void setTextOn(CharSequence textOn) {
        mTextOn = textOn;
    }     public CharSequence getTextOff() {
        return mTextOff;
    }     protected void onFinishInflate() {
        super.onFinishInflate();
        updateReferenceToIndicatorDrawable(getBackground());
    }     @Override
    public void setBackgroundDrawable(Drawable d) {
        super.setBackgroundDrawable(d);
        updateReferenceToIndicatorDrawable(d);
    }     private void updateReferenceToIndicatorDrawable(Drawable
backgroundDrawable) {
        if (backgroundDrawable instanceof LayerDrawable) {
            LayerDrawable layerDrawable = (LayerDrawable)
backgroundDrawable;
            mIndicatorDrawable =
                
   layerDrawable.findDrawableByLayerId(com.android.internal.R.id.toggle);
        }
    }
    @Override
    protected void drawableStateChanged() {
        super.drawableStateChanged();
        if (mIndicatorDrawable != null) {
            mIndicatorDrawable.setAlpha(isEnabled() ? NO_ALPHA :
(int) (NO_ALPHA * mDisabledAlpha));
        }
    }
}

  1. AsyncTask实例代码演示Android异步职分

上次大家讲到了Android提供了叁个较线程更简便的处理多职务的不二法门AsyncTask异步职责类,相对于线程来说AsyncTask对于简易的任务处理更安全,其内部的完结格局应用了Android的Handler机制,对于广泛的文书下载能够行使AsyncTask类来处理,在Browser浏览器中正是用了此类下载Web服务器ULacrosseL的Favicon图标。 
 首先Android123以简单的下载例子演示该类的大体结构,如下 private class
DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
    protected Long doInBackground(URL… urls) {
        int count = urls.length;
        long totalSize = 0;
        for (int i = 0; i < count; i++) {
            totalSize += Downloader.downloadFile(urls);
            publishProgress((int) ((i / (float) count)100));
        }
        return totalSize;
    }
    protected void onProgressUpdate(Integer… progress) {
        setProgressPercent(progress[0]);
    }
    protected void onPostExecute(Long result) {
        showDialog(“Downloaded ” + result + ” bytes”);
    }
}   最后我们实施 DownloadFilesTask().execute(url1, url2, url3);
即可。   在Android浏览器中下载Favicon图标的落到实处如下: class
DownloadTouchIcon extends AsyncTask<String, Void, Bitmap> {
    private final ContentResolver mContentResolver;
    private final Cursor mCursor;
    private final String mOriginalUrl;
    private final String mUrl;
    private final String mUserAgent;
    /\
package */ BrowserActivity mActivity;     public
DownloadTouchIcon(BrowserActivity activity, ContentResolver cr,
            Cursor c, WebView view) { //构造方法
        mActivity = activity;
        mContentResolver = cr;
        mCursor = c;
        mOriginalUrl = view.getOriginalUrl();
        mUrl = view.getUrl();
        mUserAgent = view.getSettings().getUserAgentString();
    }     public DownloadTouchIcon(ContentResolver cr, Cursor c,
String url) { //实现本类的组织
        mActivity = null;
        mContentResolver = cr;
        mCursor = c;
        mOriginalUrl = null;
        mUrl = url;
        mUserAgent = null;
    }     @Override
    public Bitmap doInBackground(String… values) { 
 //返回Bitmap类型
        String url = values[0];         AndroidHttpClient client =
AndroidHttpClient.newInstance(mUserAgent);
        HttpGet request = new HttpGet(url);    
   HttpClientParams.setRedirecting(client.getParams(), true);
//处理302等重定向问题         try {
            HttpResponse response = client.execute(request);          
  if (response.getStatusLine().getStatusCode() == 200) { //如果OK
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    InputStream content = entity.getContent();
//将图标保存到InputStream中,因为是二进制内容
                    if (content != null) {
                        Bitmap icon = BitmapFactory.decodeStream(
//从流中取出Bitmap,那里运用了BitmapFactory类的静态方法decodeStream
                                content, null, null);
                        return icon;
                    }
                }
            }
        } catch (IllegalArgumentException ex) {
            request.abort();
        } catch (IOException ex) {
            request.abort();
        } finally {
            client.close();
        }
        return null;
    }     @Override
    protected void onCancelled() {
        if (mCursor != null) {
            mCursor.close();
        }
    }     @Override
    public void onPostExecute(Bitmap icon) {
          if (mActivity != null) {
             mActivity.mTouchIconLoader = null;
        }         if (icon == null || mCursor == null ||
isCancelled()) {
            return;
        } 
   最后图标要保存到浏览器的中间数据库中,系统先后均保存为SQLite格式,Browser也不例外,因为图片是二进制的之所以采用字节数组存储数据库的BLOB类型 
       final ByteArrayOutputStream os = new ByteArrayOutputStream();
        icon.compress(Bitmap.CompressFormat.PNG, 100, os);
//将Bitmap压缩成PNG编码,质量为100%存储
        ContentValues values = new ContentValues();
//构造SQLite的Content对象,这里也足以使用raw sql代替
    
   values.put(Browser.BookmarkColumns.TOUCH_ICON,os.toByteArray());
//写入数据库的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();
    }

 本次Android开发网通过七个AsyncTask类演示了五体系型的职责构造,那里我们小心重返类型,本节演示了Android平台上Content
Provider、AsyncTask、Bitmap、HTTP以及Stream的连锁操作,大家哪些想神速提升成本程度其实若是明白谷歌(Google)怎么样去完成Android系统平常构架就足以轻松入门谷歌(Google)移动平台。
*

  1. Android自定义View实例AnalogClock源码

本着Android底层View的直接协会很多网民没有实战经验,这次Android开发网结合当下平台开源代码一起通过AnalogClock类来精晓View的第2手接轨。AnalogClock就是Home
Screen上的极度带有两根指针的表盘类。它的落成我们直接从开源代码能够理解到: 
 public class AnalogClock extends View {
    private Time mCalendar;     private Drawable mHourHand; //时针
    private Drawable mMinuteHand; //分针
    private Drawable mDial; //表盘背景     private int mDialWidth;
//表盘宽度
    private int mDialHeight; //表盘中度     private boolean mAttached;
//附着情状     private final Handler mHandler = new Handler();
//定多少个Handler类完毕革新时间
    private float mMinutes;
    private float mHour;
    private boolean mChanged; //时间是或不是改变     public
AnalogClock(Context context) {
        this(context, null);
    }     public AnalogClock(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }     public AnalogClock(Context context, AttributeSet attrs,
                       int defStyle) {
        super(context, attrs, defStyle);
        Resources r = mContext.getResources();
        TypedArray a =
                context.obtainStyledAttributes(
                        attrs,
com.android.internal.R.styleable.AnalogClock, defStyle, 0);       
 mDial =
a.getDrawable(com.android.internal.R.styleable.AnalogClock_dial);
//加载表盘能源
        if (mDial == null) {
            mDial =
r.getDrawable(com.android.internal.R.drawable.clock_dial);
        }         mHourHand =
a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_hour);
//加载时针图片财富
        if (mHourHand == null) {
            mHourHand =
r.getDrawable(com.android.internal.R.drawable.clock_hand_hour);
        }         mMinuteHand =
a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_minute);
//加载分针图片
        if (mMinuteHand == null) {
            mMinuteHand =
r.getDrawable(com.android.internal.R.drawable.clock_hand_minute);
        }         mCalendar = new Time(); //获取当前系统时间       
 mDialWidth = mDial.getIntrinsicWidth(); //获取表盘图片的增长幅度
        mDialHeight = mDial.getIntrinsicHeight(); //高度,同上
    }     @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();         if (!mAttached) {
            mAttached = true;
            IntentFilter filter = new IntentFilter();
//注册三个音讯过滤器,获取时间变更、时区改变的action            
filter.addAction(Intent.ACTION_TIME_TICK);
            filter.addAction(Intent.ACTION_TIME_CHANGED);
            filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);       
     getContext().registerReceiver(mIntentReceiver, filter, null,
mHandler);
        }           mCalendar = new Time();         onTimeChanged();
    }     @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (mAttached) {
            getContext().unregisterReceiver(mIntentReceiver);
//反注册新闻过滤器
            mAttached = false;
        }
    }     @Override
    protected void onMeasure(int widthMeasureSpec, int
heightMeasureSpec) {         int widthMode =
MeasureSpec.getMode(widthMeasureSpec);
        int widthSize =  MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize =  MeasureSpec.getSize(heightMeasureSpec);    
    float hScale = 1.0f;
        float vScale = 1.0f;         if (widthMode !=
MeasureSpec.UNSPECIFIED && widthSize < mDialWidth) {
            hScale = (float) widthSize / (float) mDialWidth;
        }         if (heightMode != MeasureSpec.UNSPECIFIED &&
heightSize < mDialHeight) {
            vScale = (float )heightSize / (float) mDialHeight;
        }         float scale = Math.min(hScale, vScale);       
 setMeasuredDimension(resolveSize((int) (mDialWidth * scale),
widthMeasureSpec),
                resolveSize((int) (mDialHeight * scale),
heightMeasureSpec));
    }     @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mChanged = true;
    } 
   首要的绘图重写View的onDraw方法,大家能够看来通过canvas实例直接显示器@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);         boolean changed = mChanged;
        if (changed) {
            mChanged = false;
        }         int availableWidth = mRight – mLeft;
        int availableHeight = mBottom – mTop;         int x =
availableWidth / 2;
        int y = availableHeight / 2;         final Drawable dial =
mDial;
        int w = dial.getIntrinsicWidth();
        int h = dial.getIntrinsicHeight();         boolean scaled =
false;         if (availableWidth < w || availableHeight < h)
{
            scaled = true;
            float scale = Math.min((float) availableWidth / (float)
w,
                                   (float) availableHeight / (float)
h);
            canvas.save();
            canvas.scale(scale, scale, x, y);
        }         if (changed) {
            dial.setBounds(x – (w / 2), y – (h / 2), x + (w / 2), y +
(h / 2));
        }
        dial.draw(canvas);         canvas.save();
        canvas.rotate(mHour / 12.0f * 360.0f, x, y);
//总结时针旋转的角度,android123提醒正是10分时针图片的团团转角度,直接反应的正是表面上卓绝针的时日
        final Drawable hourHand = mHourHand;
        if (changed) {
            w = hourHand.getIntrinsicWidth();
            h = hourHand.getIntrinsicHeight();
            hourHand.setBounds(x – (w / 2), y – (h / 2), x + (w / 2),
y + (h / 2));
        }
        hourHand.draw(canvas);
        canvas.restore();         canvas.save();
        canvas.rotate(mMinutes / 60.0f * 360.0f, x, y);
//同理,分针旋转的角度         final Drawable minuteHand =
mMinuteHand;
        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();         if (scaled) {
            canvas.restore();
        }
    }     private void onTimeChanged()
{  //获取时间转移,总结当前的时分秒
        mCalendar.setToNow();         int hour = mCalendar.hour;
        int minute = mCalendar.minute;
        int second = mCalendar.second;         mMinutes = minute +
second / 60.0f;
        mHour = hour + mMinutes / 60.0f;
        mChanged = true;
    }     private final 布RhodescastReceiver mIntentReceiver = new
BroadcastReceiver() { //监听获取时间变更action
        @Override
        public void onReceive(Context context, Intent intent) {
            if
(intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)) {
                String tz = intent.getStringExtra(“time-zone”);
                mCalendar = new
Time(TimeZone.getTimeZone(tz).getID());
            }             onTimeChanged(); //获取新的年华
            invalidate();
//刷新显示屏,强制类调用onDraw方法达成分针时针的过往
        }
    };   
看了本例依照,Android开发很简单吗,感兴趣的网络朋友能够为本程序参预一个秒针,可是Android123唤起网上朋友的是唯恐对此电池,以及系统运维功效发生一定的影响,然则作为练兵我们能够试一试。

  1. ArrayList LinkedList Set HashMap介绍

  在Android开发中大家日常索要对数据开展分类和操作,对于轻量级的数据存款和储蓄大家或者不须要利用SQLite或成效以及类库不周全的XML,由于SharedPreferences不享有数据枚举方法,假使单独是3个String或Int数组能够因此3个标记分割统一筹划外,我们依旧必不可缺来看望Android也许说Java提供的底子数据类型帮助类ArrayList
LinkedList Set
HashMap的介绍,如果你纯熟C++的STL或Boost库能够略过本文。   
在Java中提供了Collection和Map接口。在那之中List和Set继承了Collection接口;同时用Vector、ArrayList、LinkedList四个类实现List接口,HashSet、TreeSet达成Set接口。间接有HashTable、HashMap、TreeMap完结Map接口。 
   Vector基于Array的List,性能也就不容许当先Array,并且Vector是“sychronized”的,那些也是Vector和ArrayList的绝无仅有的不一样。 
   ArrayList:同Vector一样是3个基于Array的,可是不相同的是ArrayList不是同步的。所以在品质上要比Vector优越一些。Android123唤起我们适用于顺序性的搜索 
   LinkedList:分裂于前面三种List,它不是基于Array的,作为链表数据结构格局,所以不受Array品质的范围。当对LinkedList做添加,删除动作的时候假设改变nextNode的相关新闻就能够达成了所以它适合于进行多次举办插队和删除操作。那正是LinkedList的优势,当然对于成分的职责获取等地方就没有很多。 
   List:         1.
拥有的List中不得不容纳单个差异类型的指标组成的表,而不是Key-Value键值对。例如:[
tom,1,c ];         2.
装有的List中能够有一致的要素,例如Vector中得以有 [ tom,koo,too,koo
];         3. 拥有的List中得以有null成分,例如[ tom,null,1 ];    
    4.
基于Array的List(Vector,ArrayList)适合查询,而LinkedList(链表)适合添加,删除操作。
就算Set同List都落实了Collection接口,可是他们的达成方式却大分化。List基本上都以以Array为底蕴。可是Set则是在HashMap的基本功上来贯彻的,那一个正是Set和List的常有不一样。 
  
 HashSet:HashSet的储存情势是把HashMap中的Key作为Set的附和存储项,HashMap的key是无法有再一次的。HashSet能快捷稳定二个因素,可是放到HashSet中的对象急需贯彻hashCode()方法0。 
   TreeSet:将放入个中的成分按序存放,那就要求您放入其中的对象是可排序的。TreeSet区别于HashSet的有史以来是TreeSet是平稳的。它是由此SortedMap来达成的。 
   Set总计: 1. Set完毕的根基是Map(HashMap); 2.
Set中的成分是不能重新的,借使应用add(Object
obj)方法添加已经存在的靶子,则会覆盖前边的对象,无法包涵五个成分e一 、e2(e1.equals(e2))。 
   Map是一种把键对象和值对象开始展览关联的器皿,Map有二种相比较常用的贯彻:
HashTable、HashMap和TreeMap。 
   HashMap也应用了哈希码的算法,以便飞速搜索二个键, 
   TreeMap则是对键按序存放,由此它有局地扩张的艺术,比如firstKey(),lastKey()等。 
   HashMap和Hashtable的界别。
HashMap允许空(null)键(key)或值(value),由于非线程安全,作用上大概高于Hashtable。
Hashtable不容许空(null)键(key)或值(value)。   
有关更加多实用的Android开发技术大家将在后头的小说中最主要介绍。

  1. ConditionVariable Android线程同步

ConditionVariable类位于android.os.ConditionVariable,它能够扶助Android线程同步。在SDK上的介绍ConditionVariable差别于标准Java位于java.lang.Object
wait() 和 notify() ,那个类能够等待本身,那就代表 open(), close() 和
block() 恐怕会假死 ,倘诺使用ConditionVariable类的open()在调用 block()
此前, block() 将不会卡住,相反将会回到立时。    该类一共有多少个艺术   
boolean  block(long timeout)
  阻止当前线程知道原则是open,或直到超时,那里参数long
timeout为超时设置,Android123唤起我们假诺你们从事过Win32支出,这一个法子类似DWORubiconD
WaitForSingleObject(HANDLE hHandle,DWO奥迪Q5D dwMilliseconds); 函数。 
 void  block()
  阻止当前线程知道原则 open ,是地点的无超时等待重载版本。 
 void  close()
重置条件为 close状态。 void  open()
Open条件,释放具无线程的阻塞. 
 ConditionVariable在开立即还有一种构造方法是 public ConditionVariable
(boolean state) ,倘使为true,私下认可时为opened,如若为false则是closed.
,暗中认可public ConditionVariable () 为close().

53.Android支出之Eclipse调节和测试技巧

运用谷歌(Google)提供的ADT插件能够在Eclipse上很自在的调节和测试Android程序,大家切换到DDMS标签,选取“Devices”标签,大家能够看出会并发类似上边包车型客车Debug
Process(调试进程)、Update Threads(更新线程)、Update
Heap(更新堆)、Cause GC(引起垃圾回收)、Stop Process(停止进度)、Screen
Capture(荧屏截图)、Reset adb(重启Android Debug Bridge) 
 那里咱们就足以很好的阅览Android程序运维时的各样景况,比如进度消息、线程分析、堆内部存款和储蓄器的占据,停止三个进度,当然那一个操作都以在DDMS框架下开始展览的,日程开发的顺序是无力回天实施调用的。借使赶上adb调节和测试桥运维不安宁时得以选取reset
adb来再次启航adb.exe进程,整个界面如图: 图片 5诸多网上朋友对于有个别常的Android规程序品质测试、文件管理或显示器截图均选用Eclipse中的DDMS插件来查阅,其实通过SDK中提供的Dalvik
Debug
Monitor能够很好的调节和测试Android程序,那里能够更直观的切实可行设备的各类新闻,除了Logcat、VM
Heap堆查看、Thread线程状态外,在菜单的Device中得以找到Screen
capture来截图、File Explorer进行文件同步操作,使用Show process
status能够体现设备当前的长河意况,以及
连忙的过滤Logcat消息,能够分析无线状态radio state、程序状态app
state等等。那里辅助模拟器和真机的来得,该工具得以再android-sdk-windows-1.5_r1\tools\ddms.bat找到,方今我们测试环境为Windows平台,下次描述下CentOS中的操作,如图: 图片 6Android品质与调节很重点  用于手持的运动设备,Android软件质量上急需多加考虑。首先Java
VM在财富占用上支付是一点都不小的,很多垃圾GC处理体制直接影响到内部存款和储蓄器释放和全数平台运转的流畅度。 
 1.节省电量 
 手提式有线电话机软件必须考虑的标题是省电,假设急需大型处理尽量由服务器处理,直接把结果再次来到到手持设备上。多线程也是一种浪费的运用,不过I/O存款和储蓄必需那样才能确定保障流畅度,线程的不通将会稳中有降用户体验,但是线程间切换调度的支付平素是首要。Android在DDMS中参预了Thread查看。 
 2.内部存款和储蓄器占用 
 在Eclipse+ADT插件的开发方式中,大家在DDMS中可以观察Heap堆内存的显示,Android开发网提醒的是Java内部存款和储蓄器分配格局的标题,尽量产生少的目的,比如字符串操作即使连加相比多,能够行使StringBuilder代替String类。在玩乐支付中日常利用的图片能够由此切片的章程从三个大的png图片上截取,或然放在gif文件作为逐帧保存,那样能够共用文件头减小体积。 
 3.调节工具   Android调节和测试工具关键是模拟器中的Dev
Tools和DDMS中的Logcat查看。当然模拟器自带的Dev
Tools在遵从上照旧很详细的,能够显得CPU占用率,内部存款和储蓄器使用量,在单元测试时需求多加辨析。 Android开发工具Dev
Tools介绍
ndroid提供了好多支出调节和测试工具除了ADB、TraceView、Logcat外,明天那一个名为Dev
Tools
的Android开发调节和测试工具隐藏在Android模拟器中,为大家提供了精锐的调剂支持。大家在成效表中找到Dev
Tools,运维后得以看来有成都百货上千条条框框,比如Development
Settings,用来开发设置,进入后大家见到了例如Show CPU
Usage那样的实用功能彰显CPU占用率,协助Android开发人士分析当前软件质量情状,明日就分析下Development
Settings中的选项: Wait for debugger 等待调节和测试器
Enable ADB 启用ADB(android调试桥)
Show running processs (展现运转中的进度)
Show screen updates (显示屏幕更新) 
 上边是一些好端端的调剂选项,Android开发网络朋友情提醒开启那么些选取后只怕会影响运维成效,那个探测选项也是CPU敏感的。
Immediately destroy activites (即刻销毁activities)
Show CPU usage (显示CPU占用率)
Show background (显示东京(Tokyo))
Show Sleep state on LED (在蛰伏状态下LED开启)
Keep screen on while plugged in (保持显示屏开启当插入后)
Show GTalk service connection status (突显GTalk服务连接景况) 

发表评论

电子邮件地址不会被公开。 必填项已用*标注