Android开发网上的一对关键知识点[经验分享]

  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所在的叠,可以利用一个内嵌的办法限制显示。

除此以外,大店好像不差钱买几个服务器,雇几个人口保护他的数额,如果她们之经营管理者担心自己之多少安全的语句。银行敢于用云计算么?不好说。。。

  1. 怎样判断Android手机当前是不是联网?

对此小企业以及个人用户呢,小软件还得装了当地,否则用个软件还得上网,除非到上上网速度以及地面速度没有啥区别,这得相当及何时什么。。。

万一起开发一个网下的次第,首先考虑是否搭网络,在Android手机中判断是否联网可经
ConnectivityManager
类的isAvailable()方法判断,首先取得网络通讯类的实例
ConnectivityManager
cwjManager=(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
,使用cwjManager.getActiveNetworkInfo().isAvailable();
来返回是否可行,如果为True则意味着即Android手机已经联网,可能是WiFi或GPRS、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,当然编码器也有好多假设RGB565、RGB888。作为一如既往栽逐像素的亮对象实施效率高,但是缺点也够呛明朗存储效率低。我们领略吧同一栽存储对象比较好。 
 Drawable –
作为Android平下通用的图样对象,它好装常用格式的图像,比如GIF、PNG、JPG,当然也支持BMP,当然还提供部分尖端的可视化对象,比如渐变、图形等。 
 Canvas –
名为画布,我们得作为是均等种植处理过程,使用各种措施来管理Bitmap、GL或者Path路径,同时她好兼容Matrix矩阵类给图像做旋转、缩放等操作,同时Canvas类还提供了裁剪、选取等操作。 
  Paint –
我们好管其看作一个图画工具,比如画笔、画刷。他保管了每个图案工具的书体、颜色、样式。 
 如果波及一些Android游戏开发、显示特效可以经这些底层图形类来很快落实自己的动。 

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

有些网友会发现Activity在切换到后台或布局从横屏LANDSCAPE切换至PORTRAIT,会重切换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.循环运用 
 平时当看一个特性之时节效率远比一个恒定变量低,如果你的循环估计次数常常超过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文件夹下放一个图名吧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,
UpdateService.class)); //避免ANR,所以Widget中启了单劳务
    }     public static class UpdateService extends Service {
        @Override
        public void onStart(Intent intent, int startId) {
            // Build the widget update for today
            RemoteViews updateViews = buildUpdate(this);            
ComponentName thisWidget = 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,
5000,1000);  //在1秒后各个5秒执行同样差定时器中之道,比如本文也调用log.v打印输出。 
 如果想收回可以调用下面方法,取消定时器的推行   
while(!mTimerTask.cancel());
      mTimer.cancel(); 
 最后Android123提示大家,如果拍卖的物比耗时还是开个线程比较好,Timer还是碰头死主线程的尽,更像是一律种信息的实行办法。当然比Handler的postDelay等办法还符合处理计划任务。

13.Android下Icon大小在不同分辨率下定义

对此Android平台来说,不同分辨率下Icon的分寸设计有不同之求,对于眼前主流的HDPI即WVGA级别来说,通常hdpi的采用icon大小也72×72,而规范的mdpi即hvga为48×48,对于眼前HTC和Motorola推出的一些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。
对于一个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的APIDemo和Samples   3. 左右GIT开源代码   4.
几近矣解Android开源项目,学习人家的伎俩写程序。

  1. Android数组排序常见方式

  Android的数组排序方式大多采用了Sun原生的Java
API实现,常用之有Comparator接口实现compare方法和Comparable接口的compareTo方法,我们对一个数组列表比如ArrayList可以透过就简单独接口进行排序和比,这里Android123被大家一个事例
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相了产国内的好像Market客户端设计,基本上还不曾使用非常好之内存管理机制和缓存处理。 
 如果仔细的网友或发现Android
Market客户端载入时,每个列表项的图标是异步刷新显示的,但当我们迅速的朝向生滚动到得数量仍50独,再向回滚动时或者咱们来看了一部分App的图标又重新开加载,当然这等同进程也许是从SQLite数据库被缓存的,但是在内存中已经由此类似SoftReference的法门管理内存。 
 在Java中内存管理,引用分为四坏类,强引用HardReference、弱引用WeakReference、软引用SoftReference和虚引用PhantomReference。它们的分也十分明白,HardReference对象是不怕虚拟机内存吃紧抛来OOM也非见面招这同引用的目标为回收,而WeakReference等又契合给一些数码不多,但体积小大之目标,在就四独援中,它是绝轻受垃圾回收的,而我们对于显示类似Android
Market中每个应用之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一样去动态获取方式的地点。当然效率要根据复杂程度而决定,一般不怎么复杂的处理性能损失或跨越20%,对于有些繁杂的关联Java自动类型转换判断,执行时间或是直引用的上千倍增,所以最终我们调试时得考虑性能问题。 
 2. 盖反射是动态的,所以需要处理过剩不胜,不然Dalvik崩溃出Force
Close的几率会坏过多,很粗略的一个反光就需要至少3个可怜捕获,本身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的道,不仅调用上更简单,经过实测更牢靠一些,Google在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顾名思义就是层图形对象。下面直接用一个简短的代码表示: 
   Bitmap bm =
BitmapFactory.decodeResource(getResources(),R.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意味数组的亚独要素,为白色
        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)
其中第一独参数为层的索引号,后面的季单参数分别吗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方法

成千上万早晚咱们感觉Google在设计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(R.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(R.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(R.raw.cwj);    方法二 
 工程根目录下之assets文件夹着存放,比如assets/cwj.dat
这样我们采取下的代码   AssetManager am = context.getAssets();  
  InputStream is = am.open(cwj.dat); 
   这里Android123提拔大家Google的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凡是一个吓习惯,内容如下
<?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就足以擅自使用了
}
以上两栽艺术吃,参数的终极一个数值也默认的,如果您来非知底的地方得来函到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” />   
这里我们利用了一个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,以后的篇章被拿会晤讲到屏幕触控的切切实实处理onTouchEvent以及Sensor重力感应等措施。 
 2. 刷新view的点子这里主要发生invalidate(int l, int t, int r, int b)
刷新局部,四单参数分别吗不当、上、右、下。整个view刷新
invalidate(),刷新一个矩形区域 invalidate(Rect dirty)
,刷新一个表征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.onTouchEvent(event); //让父类处理屏幕触控事件
   }    @Override
   public boolean onKeyDown(int keyCode, KeyEvent event) {
//处理按键事件,响应的轨道球事件也 public boolean onTrackballEvent
(MotionEvent 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_CENTER: //处理中键按下
         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) //绘制一个门道,参数一为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  setARGB(int a, int r, int g, int
b)  设置Paint对象颜色,参数一为alpha透明通道
void  setAlpha(int a)  设置alpha不透明度,范围吗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直达写一个红点
  } 
 下一次Android123用会见切实讲到有力的Path路径,和字体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, KeyEvent) 有按键按下后触发 onKeyUp(int, KeyEvent)
有按键按下后弹起时触发 onTrackballEvent(MotionEvent) 轨迹球事件
onTouchEvent(MotionEvent) 触屏事件 onFocusChanged(boolean, int, Rect)
当View获取或去焦点时触发  onWindowFocusChanged(boolean)
当窗口包含的view获取或失去焦点时触发 onAttachedToWindow()
当view被附着到一个窗口时触发 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(R.color.xxx));  //从Res中找到名为xxx的color颜色定义
   canvas.drawRect(0, 0, getWidth(), getHeight(), paintBackground);
//设置当前画布的背景颜色为paintBackground中定义之水彩,以0,0作为为起点,以目前画布的增长率与惊人也根本就是整块画布来填充。 
  
 具体的呼吁查看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来促成这些,而Google
Android中涉及到展示的啊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
接口回调中可以通过下三独泛类可友善定义具体的实现,比如第一单还改格式和出示画面。
abstract void  surfaceChanged(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.Android为每个程序分配的对内存好透过Runtime类的totalMemory()
freeMemory()
两独主意获得VM的片内存信息,对于网heap内存获取,可以经过Dalvik.VMRuntime类的getMinimumHeapSize()
方法取得最小可用堆内存,同时展示释放软引用得调用该类的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平台,其实Google为咱提供好了文件大小和时间日期解析类,它位于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, 1970
GMT, returns a CharSequence containing the requested date. 
 我们或看了第一独参数均为inFormat这是一个CharSequence接口的String类型,它提供了灵活的时空格式解析字符串描述,Android开发网提示大家注意分寸写如区别,如 
  April 6, 1970 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, 1987 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() {  //大多数总人口或略直接这样勾画
        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的HttpURLConnection类方法处理,比要协调定义一次于呼吁header可以经过setRequestProperty设置,而我辈要得到的Http
Web Server状态可以经HttpURLConnection.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(VERTICAL);
设置布局也垂直    TextView textControl = new
TextView(this);//如果起一个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载入效果,通常游戏要大型软件打开时可能需要一个放解析资源的经过,需要一个前台的动画播放以及后台的逻辑处理线程配合,当然对简易的软件为可以加以一个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();    //关闭自己这开场屏
            }  
        }, 5000);   //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.RESTART_PACKAGES”/>这个权力,不过我们注意到,长论Home键可以望以前程序的周转,同时可迅速的切换回来。这即是Android独有的次生命周期管理机制
Activity历史栈。 
 我们于一个寻常的先后主窗口A中开拓了一个窗口B,而窗口B打开了窗口C,但是按照下Back键后结果大于了预期,是的即刻就是是Activity的history
stack的故,在数据结构中栈是FIFO的,阻止我们无乐意看的状的产生则足以于打开新Activity时添加标记FLAG_ACTIVITY_NO_HISTORY,代码如下: 
   Intent i= new Intent(this, cwj.class);  
    i.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); 
 //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或SD卡上的文本,分段映射到内存中展开改动处理,这样即使因此快的RAM代替了ROM或SD卡,性能自然增长不掉,对于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时首要采取流,这里Android开发网给大家一个造福的类,可以拍卖InputStream输入流转吗String字符串,在效率达,我们使用了字符串拼接StringBuilder类减少内存碎片以及BefferedReader类实现一个缓存。 
   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服务器URL的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系统健康构架就可轻松入门谷歌移动平台。
*

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

本着Android底层View的第一手组织很多网友没有实战经验,本次Android开发网结合当前平台开源代码一起经过AnalogClock类来掌握View的一直接轨。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提示就是颇时针图片的旋转角度,直接反应的就是表面上老针的流年
        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 BroadcastReceiver 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不备数据枚举方法,如果只是是一个String或Int数组可以经一个标志分割统筹外,我们尚是任重而道远来探望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一样是一个基于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)方法添加已经存在的目标,则会挂前的靶子,不能够包含两独元素e1、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() 将不会见堵塞,相反以会见回就。    该类一共来4独章程   
boolean  block(long timeout)
  阻止当前线程知道原则是open,或直到超时,这里参数long
timeout为过设置,Android123唤起大家如果你们从了Win32支付,这个法子类似DWORD
WaitForSingleObject(HANDLE hHandle,DWORD 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 (显示都)
Show Sleep state on LED (在蛰伏状态下LED开启)
Keep screen on while plugged in (保持屏幕被当插入后)
Show GTalk service connection status (显示GTalk服务连接状态) 

发表评论

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