黄色毛片在线观看,亚洲人成网站77777·c0m,美女免费黄色av网站在线观看,五月丁香综合网站婷婷,噜噜噜噜私人影院av线观看,天天色av,在线观看黄片欧洲

Android開發(fā)網(wǎng)上的一些重要知識點[經(jīng)驗分享]

文章分類:公司動態(tài) 發(fā)布時間:2013-07-27 原文作者:admin 閱讀( )

1. android單實例運行方法

我們都知道Android平臺沒有任務管理器,而內(nèi)部App維護者一個Activity history stack來實現(xiàn)窗口顯示和銷毀,對于常規(guī)從快捷方式運行來看都是startActivity可能會使用FLAG_ACTIVITY_NEW_TASK標記來打開一個新窗口,比如Launcher,所以考慮單任務的實現(xiàn)方法比較簡單,首先Android123糾正下大家一種錯誤的方法就是直接在androidmanifest.xml的application節(jié)點中加入android:launchMode="singleInstance"這句,其實這樣將不會起到任何作用,Apps內(nèi)部維護的歷史棧作用于Activity,我們必須在activity節(jié)點中加入android:launchMode="singleInstance" 這句才能保證單實例,當然一般均加在主程序啟動窗口的Activity。

2. px像素如何轉(zhuǎn)為dip設備獨立像素

最近有網(wǎng)友問如何將px像素轉(zhuǎn)為dip獨立設備像素,由于Android的設備分辨率眾多,目前主流的為wvga,而很多老的設備為hvga甚至低端的qvga,對于兼容性來說使用dip無非是比較方便的,由于他和分辨率無關和屏幕的密度大小有關,所以推薦使用。  px= (int) (dip*density+0.5f) //這里android開發(fā)網(wǎng)提示大家很多網(wǎng)友獲取density(密度)的方法存在問題,從資源中獲取的是靜態(tài)定義的,一般為1.0對于HVGA是正好的,而對于wvga這樣的應該從WindowsManager中獲取,WVGA為1.5 這里可以再補充一下dip,sip的知識

3. Android中動態(tài)改變ImageView大小

很多網(wǎng)友可能發(fā)現(xiàn)在layout.xml文件中定義了ImageView的絕對大小后,無法動態(tài)修改以后的大小顯示,其實Android平臺在設計UI控件時考慮到這個問題,為了適應不同的Drawable可以通過在xml的相關ImageView中加入android:scaleType="fitXY" 這行即可,但因為使用了縮放可能會造成當前UI有所變形。使用的前提是限制ImageView所在的層,可以使用一個內(nèi)嵌的方法限制顯示。

4. 如何判斷Android手機當前是否聯(lián)網(wǎng)?

如果擬開發(fā)一個網(wǎng)絡應用的程序,首先考慮是否接入網(wǎng)絡,在Android手機中判斷是否聯(lián)網(wǎng)可以通過 ConnectivityManager 類的isAvailable()方法判斷,首先獲取網(wǎng)絡通訊類的實例 ConnectivityManager cwjManager=(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); ,使用cwjManager.getActiveNetworkInfo().isAvailable(); 來返回是否有效,如果為True則表示當前Android手機已經(jīng)聯(lián)網(wǎng),可能是WiFi或GPRS、HSDPA等等,具體的可以通過ConnectivityManager 類的getActiveNetworkInfo() 方法判斷詳細的接入方式,需要注意的是有關調(diào)用需要加入<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission> 這個權限,android開發(fā)網(wǎng)提醒大家在真機上Market和Browser程序都使用了這個方法,來判斷是否繼續(xù),同時在一些網(wǎng)絡超時的時候也可以檢查下網(wǎng)絡連接是否存在,以免浪費手機上的電力資源。

5. Drawable、Bitmap、Canvas和Paint的關系

很多網(wǎng)友剛剛開始學習Android平臺,對于Drawable、Bitmap、Canvas和Paint它們之間的概念不是很清楚,其實它們除了Drawable外早在Sun的J2ME中就已經(jīng)出現(xiàn)了,但是在Android平臺中,Bitmap、Canvas相關的都有所變化。   首先讓我們理解下Android平臺中的顯示類是View,但是還提供了底層圖形類android.graphics,今天所說的這些均為graphics底層圖形接口。   Bitmap - 稱作位圖,一般位圖的文件格式后綴為bmp,當然編碼器也有很多如RGB565、RGB888。作為一種逐像素的顯示對象執(zhí)行效率高,但是缺點也很明顯存儲效率低。我們理解為一種存儲對象比較好。   Drawable - 作為Android平下通用的圖形對象,它可以裝載常用格式的圖像,比如GIF、PNG、JPG,當然也支持BMP,當然還提供一些高級的可視化對象,比如漸變、圖形等。   Canvas - 名為畫布,我們可以看作是一種處理過程,使用各種方法來管理Bitmap、GL或者Path路徑,同時它可以配合Matrix矩陣類給圖像做旋轉(zhuǎn)、縮放等操作,同時Canvas類還提供了裁剪、選取等操作。    Paint - 我們可以把它看做一個畫圖工具,比如畫筆、畫刷。他管理了每個畫圖工具的字體、顏色、樣式。   如果涉及一些Android游戲開發(fā)、顯示特效可以通過這些底層圖形類來高效實現(xiàn)自己的應用。 

6. Activity切換導致的onCreate重復執(zhí)行

部分網(wǎng)友會發(fā)現(xiàn)Activity在切換到后臺或布局從橫屏LANDSCAPE切換到PORTRAIT,會重新切換Activity會觸發(fā)一次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
     }
    }

7. Android的ImageButton問題

很多網(wǎng)友對Android提供的ImageButton有個疑問,當顯示Drawable圖片時就不會再顯示文字了,其實解決的方法有兩種,第一種就是圖片中就寫入文字,但是這樣解決會增加程序體積,同時硬編碼方式會影響多國語言的發(fā)布。第二種解決方法很簡單,通過分析可以看到ImageButton的layout,我們可以直接直接繼承,添加一個TextView,對齊方式為右側即可實現(xiàn)ImageButton支持文字右側顯示。

8. Android代碼優(yōu)化技術

1.Java內(nèi)存控制   對于字符串操作而言如果需要連加這樣的操作建議使用StringBuilder,經(jīng)過調(diào)試不難發(fā)現(xiàn)如果你的字符串每次連加,使用String需要的內(nèi)存開銷會遠大于StringBuilder,然后Android手機常規(guī)的運行內(nèi)存大約在128MB左右,對于運行多任務就需要考慮了,Android開發(fā)網(wǎng)提示因為Java有GC不需要手動釋放那么分配的時候就要格外的小心,頻繁的GC操作仍然是很影響性能的,在調(diào)試時我們可以通過logcat查看內(nèi)存釋放情況。   2.循環(huán)使用   平時在訪問一個屬性的時候效率遠比一個固定變量低,如果你的循環(huán)估計次數(shù)常常大于5,假設xxx.GetLength()方法的值一般大于5,推薦這樣寫,比如   for(int i=0;i<xxx.GetLength();i++)   這里xxx.GetLength在每次循環(huán)都要調(diào)用,必然會影響程序效率,在游戲開發(fā)中顯得更為明顯,改進的方法應該為   int j=xxx.GetLength()    for(int i=0;i<j;i++)   3.圖片的優(yōu)化   在Android平臺中2維圖像處理庫BitmapFactory做的比較智能,為了減少文件體積和效率,常常不用很多資源文件,而把很多小圖片放在一個圖片中,有切片的方式來完成,在J2ME中我們這樣是為了將少文件頭而解決MIDP這些設備的問題,而Android中雖然機型硬件配置都比較高,有關Android G1硬件配置可以參考G1手機參數(shù)以及評測,但是當資源多時這樣的運行效率還是令人滿意的,至少Dalvik優(yōu)化的還不是很夠。

9. Android開發(fā)進階之NIO非阻塞包(一)

對于Android的網(wǎng)絡通訊性能的提高,我們可以使用Java上高性能的NIO (New I/O) 技術進行處理,NIO是從JDK 1.4開始引入的,NIO的N我們可以理解為Noblocking即非阻塞的意思,相對應傳統(tǒng)的I/O,比如Socket的accpet()、read()這些方法而言都是阻塞的。   NIO主要使用了Channel和Selector來實現(xiàn),Java的Selector類似Winsock的Select模式,是一種基于事件驅(qū)動的,整個處理方法使用了輪訓的狀態(tài)機,如果你過去開發(fā)過Symbian應用的話這種方式有點像活動對象,好處就是單線程更節(jié)省系統(tǒng)開銷,NIO的好處可以很好的處理并發(fā),對于Android網(wǎng)游開發(fā)來說比較關鍵,對于多點Socket連接而言使用NIO可以大大減少線程使用,降低了線程死鎖的概率,畢竟手機游戲有UI線程,音樂線程,網(wǎng)絡線程,管理的難度可想而知,同時I/O這種低速設備將影響游戲的體驗。   NIO作為一種中高負載的I/O模型,相對于傳統(tǒng)的BIO (Blocking I/O)來說有了很大的提高,處理并發(fā)不用太多的線程,省去了創(chuàng)建銷毀的時間,如果線程過多調(diào)度是問題,同時很多線程可能處于空閑狀態(tài),大大浪費了CPU時間,同時過多的線程可能是性能大幅下降,一般的解決方案中可能使用線程池來管理調(diào)度但這種方法治標不治本。使用NIO可以使并發(fā)的效率大大提高。當然NIO和JDK 7中的AIO還存在一些區(qū)別,AIO作為一種更新的當然這是對于Java而言,如果你開發(fā)過Winsock服務器,那么IOCP這樣的I/O完成端口可以解決更高級的負載,當然了今天Android123主要給大家講解下為什么使用NIO在Android中有哪些用處。    NIO我們分為幾個類型分別描述,作為Java的特性之一,我們需要了解一些新的概念,比如ByteBuffer類,Channel,SocketChannel,ServerSocketChannel,Selector和SelectionKey。有關具體的使用,Android開發(fā)網(wǎng)將在明天詳細講解。網(wǎng)友可以在Android SDK文檔中看下java.nio和java.nio.channels兩個包了解。http://www.android123.com.cn/androidkaifa/695.html
了解下這種技術,看看在馬上要做的項目中是否用得到

10. Android Theme和Styles內(nèi)部定義解析

昨天我們講到的有關在AndroidManifest.xml中定義Activity的theme方法來實現(xiàn)無標題的方法,在使用xml讓你的Activity無標題方法 一文中講到的,很多網(wǎng)友不明白為什么這樣做,其實在Android123以前的文章中多次提到了styles樣式定義方法,今天Android開發(fā)網(wǎng)再次把一些網(wǎng)友回顧了解下android樣式的內(nèi)部定義。在一個工程的res/values/theme.xml中我們可以方便的定義自己的風格主題,比如下面的cwjTheme中我們使用了基于android內(nèi)部的白色調(diào)的背景Theme.Light,設置windowsNoTitle為true代表沒有標題,背景顏色我們使用了android內(nèi)部定義的透明,同時設置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控件我們自定義的風格就是修改下系統(tǒng)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的數(shù)據(jù)提供,在Android平臺上已經(jīng)內(nèi)置的org.json包可以很方便的實現(xiàn)手機客戶端的解析處理。下面Android123一起分析下這個例子,幫助Android開發(fā)者需要有關 HTTP通訊、正則表達式、JSON解析、appWidget開發(fā)的一些知識。 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)); //這里是打開相應的網(wǎng)頁,所以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;
        }
    }
}   有關網(wǎng)絡通訊的實體類,以及一些常量定義如下:   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返回的數(shù)據(jù)流             ByteArrayOutputStream content = new ByteArrayOutputStream();             int readBytes = 0;
            while ((readBytes = inputStream.read(sBuffer)) != -1) {
                content.write(sBuffer, 0, readBytes); //轉(zhuǎn)化為字節(jié)數(shù)組流
            }             return new String(content.toByteArray()); //從字節(jié)數(shù)組構建String
        } catch (IOException e) {
            throw new ApiException("Problem communicating with API", e);
        }
    }
} 有關整個每日維基的widget例子比較簡單,主要是幫助大家積累常用代碼,了解Android平臺 JSON的處理方式,畢竟很多Server還是Java的。

12.Android中使用定時器TimerTask類介紹

在Android平臺中需要反復按周期執(zhí)行方法可以使用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秒執(zhí)行一次定時器中的方法,比如本文為調(diào)用log.v打印輸出。   如果想取消可以調(diào)用下面方法,取消定時器的執(zhí)行    while(!mTimerTask.cancel());
      mTimer.cancel();   最后Android123提示大家,如果處理的東西比較耗時還是開個線程比較好,Timer還是會阻塞主線程的執(zhí)行,更像是一種消息的執(zhí)行方式。當然比Handler的postDelay等方法更適合處理計劃任務。
原文來自:tbkj
?