隨筆 - 33, 文章 - 0, 評(píng)論 - 12, 引用 - 0
          數(shù)據(jù)加載中……

          android 保存圖片到數(shù)據(jù)庫(kù)

          方法一:
          Java代碼 復(fù)制代碼
          1. public void saveIcon(Bitmap icon) {   
          2.         if (icon == null) {   
          3.             return;   
          4.         }   
          5.   
          6.         // 最終圖標(biāo)要保存到瀏覽器的內(nèi)部數(shù)據(jù)庫(kù)中,系統(tǒng)程序均保存為SQLite格式,Browser也不例外,因?yàn)閳D片是二進(jìn)制的所以使用字節(jié)數(shù)組存儲(chǔ)數(shù)據(jù)庫(kù)的   
          7.         // BLOB類(lèi)型   
          8.         final ByteArrayOutputStream os = new ByteArrayOutputStream();   
          9.         // 將Bitmap壓縮成PNG編碼,質(zhì)量為100%存儲(chǔ)           
          10.         icon.compress(Bitmap.CompressFormat.PNG, 100, os);    
          11.         // 構(gòu)造SQLite的Content對(duì)象,這里也可以使用raw   
          12.         ContentValues values = new ContentValues();    
          13.         // 寫(xiě)入數(shù)據(jù)庫(kù)的Browser.BookmarkColumns.TOUCH_ICON字段   
          14.         values.put(Browser.BookmarkColumns.TOUCH_ICON, os.toByteArray());    
          15.            
          16.         DBUtil.update(....);//調(diào)用更新或者插入到數(shù)據(jù)庫(kù)的方法   
          17.     } 


          方法二:如果數(shù)據(jù)表入口時(shí)一個(gè)content:URI

           

          Java代碼 復(fù)制代碼
          1. import android.provider.MediaStore.Images.Media;   
          2. import android.content.ContentValues;   
          3. import java.io.OutputStream;   
          4.   
          5. // Save the name and description of an image in a ContentValues map.     
          6. ContentValues values = new ContentValues(3);   
          7. values.put(Media.DISPLAY_NAME, "road_trip_1");   
          8. values.put(Media.DESCRIPTION, "Day 1, trip to Los Angeles");   
          9. values.put(Media.MIME_TYPE, "image/jpeg");   
          10.   
          11. // Add a new record without the bitmap, but with the values just set.   
          12. // insert() returns the URI of the new record.   
          13. Uri uri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);   
          14.   
          15. // Now get a handle to the file for that record, and save the data into it.   
          16. // Here, sourceBitmap is a Bitmap object representing the file to save to the database.   
          17. try {   
          18.     OutputStream outStream = getContentResolver().openOutputStream(uri);   
          19.     sourceBitmap.compress(Bitmap.CompressFormat.JPEG, 50, outStream);   
          20.     outStream.close();   
          21. catch (Exception e) {   
          22.     Log.e(TAG, "exception while writing image", e);   


          posted @ 2011-11-17 14:09 建華 閱讀(1667) | 評(píng)論 (0)編輯 收藏

          代碼命名

          1、成員變量(全局變量)命名首字母以m開(kāi)頭第二個(gè)字母大寫(xiě);(e.g  int mIndex = 0)                                                                                                            
          2、常量全部大寫(xiě)                                                                                                                                                                                                           3、靜態(tài)的變量命名首字母以s開(kāi)頭第二個(gè)字母大寫(xiě);(e.g  static int sIndex = 0)          

          posted @ 2011-11-04 10:03 建華 閱讀(159) | 評(píng)論 (0)編輯 收藏

          android混淆apk出錯(cuò)Proguard returned with error code 1. See console解決辦法”

          原文出自:http://blog.csdn.net/aa4790139/article/details/6754230 

          第一種情況:
          Proguard returned with error code 1. See console 
          Error: C:/Documents (系統(tǒng)找不到指定文件) 
          后來(lái)發(fā)現(xiàn)是因?yàn)閷⒄麄€(gè)工程放到了桌面上,而桌面的目錄是C:/Documents and Settings/Administrator/桌面,在這里面有空格,而proguard進(jìn)行發(fā)編譯的時(shí)候是不允許有空格的
          如果換了正確路徑還不好用的話,直接刪除proguard就好了

          注意:SDK和程序路徑最好不要有空格符

          第二種情況:

          Proguard returned with error code 1. See console 
          異常:

          java.lang.ArrayIndexOutOfBoundsException

          解決辦法:將proguard.cfg中的"-dontpreverify"改成“-dontoptimize

          參考文章:http://groups.google.com/group/android-developers/browse_thread/thread/eca3b0f5ce6ad00f

          posted @ 2011-11-02 19:56 建華 閱讀(3971) | 評(píng)論 (0)編輯 收藏

          怎么建一個(gè)自己的博客

          建一個(gè)自己的博客,既可以練習(xí)php,mysql,還能了解一些網(wǎng)站基礎(chǔ)知識(shí)。好了現(xiàn)在我就吧自己建立玩站的過(guò)程寫(xiě)下來(lái),供大家參考!過(guò)程是漫長(zhǎng)的,只有自己摸索,才能不斷增加經(jīng)驗(yàn),才能自己解決問(wèn)題!

          首先我們得要個(gè)空間,這個(gè)空間是用來(lái)放網(wǎng)頁(yè)文件滴,其實(shí)網(wǎng)站就是一個(gè)文件夾,里面放了許多網(wǎng)頁(yè),在靜態(tài)網(wǎng)頁(yè)中,當(dāng)你用瀏覽器訪問(wèn)這個(gè)文件時(shí)它會(huì)首先訪問(wèn)index.html,自己動(dòng)手做過(guò)的同學(xué)肯定知道,當(dāng)你把別人網(wǎng)站拷下來(lái)的時(shí)候體會(huì)就明顯了,我就這么干的(好像很廢話)。

          1.我前前后后申請(qǐng)了N多空間,不是空間太小,就是無(wú)法登陸,或者DNS解析不上,所以我推薦用www.simplefreeweb.com,完全免費(fèi)滴,等一晚上就把賬號(hào)密碼發(fā)過(guò)來(lái)了,后臺(tái)有很多工具mysql,phpmyadmin等等(額- -!我忘了說(shuō)一點(diǎn),懂一點(diǎn)數(shù)據(jù)庫(kù)和php的同學(xué)上手快一些,因?yàn)槟氵B數(shù)據(jù)庫(kù),表都不知道,那出現(xiàn)問(wèn)題你都不知道在哪里)。

          2.注冊(cè)好能登陸的前提下,再到cn.wordpress.org下載他們的wordpress(這是別人做好的玩站模板,直接可用,里面是php文件如果你自己有自信比他做的好,或者練習(xí)php,那就自己做吧)解壓上傳到空間,上傳工具很多,我用的是filezilla,用www.simplefreeweb.com提供的ftp站好密碼,上傳到ftp里面的www目錄下,記住上傳wordpress文件下的文件,不要把wordpress文件夾一起傳上去,要不然你要訪問(wèn)yourname.simplefreeweb.com/wordpress才能訪問(wèn)。

          3.上傳完成,用simplefreeweb給你的后臺(tái)登陸網(wǎng)址登陸,在里面建立數(shù)據(jù)庫(kù),再向數(shù)據(jù)庫(kù)添加用戶的時(shí)候一定要勾選全部權(quán)限,要不然在后面wordpress安裝的時(shí)候會(huì)連接出現(xiàn)問(wèn)題!

          4.建立好數(shù)據(jù)庫(kù)后,登陸你的網(wǎng)站yourname.simplefreeweb.com,會(huì)出現(xiàn)wordpress安裝導(dǎo)向,按照步驟就可以啦!

          5.yourname.simplefreeweb.com這個(gè)是人家的二級(jí)域名,既不個(gè)性,有很難記,所以我們得要個(gè)自己的。網(wǎng)上的頂級(jí)域名很多但價(jià)格不菲,而且申請(qǐng)麻煩,所以我建議到http://www.dot.tk申請(qǐng),很方便!

          綁定域名,就是將這個(gè)域名指向你的網(wǎng)站,方法主要是域名解析,免費(fèi)的解析商也很多,很久都沒(méi)消息(我的就是,ywww.simplefreeweb.com自帶的解析不給力啊)。但是,tk里面有個(gè)域名跳轉(zhuǎn),當(dāng)你申請(qǐng)完后把你的yourname.simplefreeweb.com填進(jìn)去,這樣當(dāng)訪問(wèn)你的域名,如我的www.liubos.k時(shí)候,直接跳到liubo.simplefreeweb.com。好處是方便,缺點(diǎn)是當(dāng)別人訪問(wèn)非主頁(yè)時(shí),還是顯示原來(lái)的網(wǎng)址!又等一晚上!第二天再訪問(wèn)自己的網(wǎng)站www.xxx.tk吧!說(shuō)到xxx,我又邪惡了,呵呵!


          posted @ 2011-10-31 11:34 建華 閱讀(2383) | 評(píng)論 (6)編輯 收藏

          android 使用contentobserver監(jiān)聽(tīng)數(shù)據(jù)庫(kù)內(nèi)容變化

               摘要: android 使用contentobserver監(jiān)聽(tīng)數(shù)據(jù)庫(kù)內(nèi)容變化在android中經(jīng)常會(huì)用到改變數(shù)據(jù)庫(kù)內(nèi)容后再去使用數(shù)據(jù)庫(kù)更新的內(nèi)容,很多人會(huì)重新去query一遍,但是這樣的問(wèn)題就是程序會(huì)特別占內(nèi)存,而且有可能會(huì)摟關(guān)cursor而導(dǎo)致程序內(nèi)存未釋放等等。其實(shí)android內(nèi)部提供了一種ContentObserver的東西來(lái)監(jiān)聽(tīng)數(shù)據(jù)庫(kù)內(nèi)容的變化。ContentObserver的構(gòu)造函數(shù)需要一個(gè)參...  閱讀全文

          posted @ 2011-10-27 22:11 建華 閱讀(4958) | 評(píng)論 (1)編輯 收藏

          Android 彩信的發(fā)送

          最近有個(gè)需求,不去調(diào)用系統(tǒng)界面發(fā)送彩信功能。做過(guò)發(fā)送短信功能的同學(xué)可能第一反應(yīng)是這樣:
          不使用 StartActivity,像發(fā)短信那樣,調(diào)用一個(gè)類(lèi)似于發(fā)短信的方法
          SmsManager smsManager = SmsManager.getDefault();
          smsManager.sendTextMessage(phoneCode, null, text, null, null);
          可以實(shí)現(xiàn)嗎? 答案是否定的,因?yàn)閍ndroid上根本就沒(méi)有提供發(fā)送彩信的接口,如果你想發(fā)送彩信,對(duì)不起,請(qǐng)調(diào)用系統(tǒng)彩信app界面,如下
                      Intent sendIntent = new Intent(Intent.ACTION_SEND,  Uri.parse("mms://"));
          	    sendIntent.setType("image/jpeg");
          	    String url = "file://sdcard//tmpPhoto.jpg";
          	    sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(url));
          	    startActivity(Intent.createChooser(sendIntent, "MMS:"));

          但是這種方法往往不能滿足我們的需求,能不能不調(diào)用系統(tǒng)界面,自己實(shí)現(xiàn)發(fā)送彩信呢?經(jīng)過(guò)幾天的努力,終于找到了解決辦法。
          第一步:先構(gòu)造出你要發(fā)送的彩信內(nèi)容,即構(gòu)建一個(gè)pdu,需要用到以下幾個(gè)類(lèi),這些類(lèi)都是從android源碼的MMS應(yīng)用中mms.pdu包中copy出來(lái)的。你需要將pdu包中的所有類(lèi)

          都拷貝到你的工程中,然后自己酌情調(diào)通。
             final SendReq sendRequest = new SendReq();
             final PduBody pduBody = new PduBody();

          final PduPart part = new PduPart();//存放附件,每個(gè)附件是一個(gè)part,如果添加多個(gè)附件,就想body中add多個(gè)part。

             pduBody.addPart(partPdu);
             sendRequest.setBody(pduBody);
             final PduComposer composer = new PduComposer(ctx, sendRequest);

          final byte[] bytesToSend = composer.make(); //將彩信的內(nèi)容以及主題等信息轉(zhuǎn)化成byte數(shù)組,準(zhǔn)備通過(guò)http協(xié)議發(fā)送到 ”http://mmsc.monternet.com”;

           第二步:發(fā)送彩信到彩信中心。
           構(gòu)建pdu的代碼:
            String subject = "測(cè)試彩信";
          		    String recipient = "接收彩信的號(hào)碼";//138xxxxxxx
          		    final SendReq sendRequest = new SendReq();
          		    final EncodedStringValue[] sub = EncodedStringValue.extract(subject);
          		    if (sub != null && sub.length > 0) {
          		    	sendRequest.setSubject(sub[0]);
          		    }
          		    final EncodedStringValue[] phoneNumbers = EncodedStringValue.extract(recipient);
          		    if (phoneNumbers != null && phoneNumbers.length > 0) {
          		    	sendRequest.addTo(phoneNumbers[0]);
          		    }
          		    final PduBody pduBody = new PduBody();
          		    final PduPart part = new PduPart();
          		    part.setName("sample".getBytes());
          		    part.setContentType("image/png".getBytes());
          		    String furl = "file://mnt/sdcard//1.jpg";
           
          		    		final PduPart partPdu = new PduPart();
          		    		partPdu.setCharset(CharacterSets.UTF_8);//UTF_16
          		    		partPdu.setName(part.getName());
          		    		partPdu.setContentType(part.getContentType());
          		    		partPdu.setDataUri(Uri.parse(furl));
          		    		pduBody.addPart(partPdu);   
           
          		    sendRequest.setBody(pduBody);
          		    final PduComposer composer = new PduComposer(ctx, sendRequest);
          		    final byte[] bytesToSend = composer.make();
           
          		    Thread t = new Thread(new Runnable() {
           
          				@Override
          				public void run() {
          					try {
          						HttpConnectInterface.sendMMS(ctx,  bytesToSend);
          //
          					} catch (IOException e) {
          						e.printStackTrace();
          					}
          				}
          			});
          		    t.start();
          發(fā)送pdu到彩信中心的代碼:
                  public static String mmscUrl = "http://mmsc.monternet.com";
          //	public static String mmscUrl = "http://www.baidu.com/";
          	public static String mmsProxy = "10.0.0.172";
          	public static String mmsProt = "80";
           
                 private static String HDR_VALUE_ACCEPT_LANGUAGE = "";
              // Definition for necessary HTTP headers.
                 private static final String HDR_KEY_ACCEPT = "Accept";
                 private static final String HDR_KEY_ACCEPT_LANGUAGE = "Accept-Language";
           
              private static final String HDR_VALUE_ACCEPT =
                  "*/*, application/vnd.wap.mms-message, application/vnd.wap.sic";
          public static byte[] sendMMS(Context context, byte[] pdu)throws IOException{
          		HDR_VALUE_ACCEPT_LANGUAGE = getHttpAcceptLanguage();
           
          		if (mmscUrl == null) {
                      throw new IllegalArgumentException("URL must not be null.");
                  }
           
                  HttpClient client = null;
                  try {
          	        // Make sure to use a proxy which supports CONNECT.
          	        client = HttpConnector.buileClient(context);
          	        HttpPost post = new HttpPost(mmscUrl);
          	        //mms PUD START
          	        ByteArrayEntity entity = new ByteArrayEntity(pdu);
          			entity.setContentType("application/vnd.wap.mms-message");
          	        post.setEntity(entity);
          	        post.addHeader(HDR_KEY_ACCEPT, HDR_VALUE_ACCEPT);
          	        post.addHeader(HDR_KEY_ACCEPT_LANGUAGE, HDR_VALUE_ACCEPT_LANGUAGE);
          	        //mms PUD END
          	        HttpParams params = client.getParams();
          	        HttpProtocolParams.setContentCharset(params, "UTF-8");
          	        HttpResponse response = client.execute(post);
           
          			LogUtility.showLog(tag, "111");
          	        StatusLine status = response.getStatusLine();
          	        LogUtility.showLog(tag, "status "+status.getStatusCode());
          	        if (status.getStatusCode() != 200) { // HTTP 200 is not success.
                      	LogUtility.showLog(tag, "!200");
                          throw new IOException("HTTP error: " + status.getReasonPhrase());
                      }
          	        HttpEntity resentity = response.getEntity();
                      byte[] body = null;
                      if (resentity != null) {
                          try {
                              if (resentity.getContentLength() > 0) {
                                  body = new byte[(int) resentity.getContentLength()];
                                  DataInputStream dis = new DataInputStream(resentity.getContent());
                                  try {
                                      dis.readFully(body);
                                  } finally {
                                      try {
                                          dis.close();
                                      } catch (IOException e) {
                                          Log.e(tag, "Error closing input stream: " + e.getMessage());
                                      }
                                  }
                              }
                          } finally {
                              if (entity != null) {
                                  entity.consumeContent();
                              }
                          }
                      }
                      LogUtility.showLog(tag, "result:"+new String(body));
                      return body;
          		}  catch (IllegalStateException e) {
          			LogUtility.showLog(tag, "",e);
          //            handleHttpConnectionException(e, mmscUrl);
                  } catch (IllegalArgumentException e) {
                  	LogUtility.showLog(tag, "",e);
          //            handleHttpConnectionException(e, mmscUrl);
                  } catch (SocketException e) {
                  	LogUtility.showLog(tag, "",e);
          //            handleHttpConnectionException(e, mmscUrl);
                  } catch (Exception e) {
                  	LogUtility.showLog(tag, "",e);
                  	//handleHttpConnectionException(e, mmscUrl);
                  } finally {
                      if (client != null) {
          //                client.;
                      }
                  }
          		return new byte[0];
          	}

          至此,彩信的發(fā)送算是完成了。
          總結(jié):android的彩信相關(guān)操作都是沒(méi)有api的,包括彩信的讀取、發(fā)送、存儲(chǔ)。這些過(guò)程都是需要手動(dòng)去完成的。想要弄懂這些過(guò)程,需要仔細(xì)閱讀android源碼中的mms這個(gè)app。還有就是去研究mmssms.db數(shù)據(jù)庫(kù),因?yàn)椴市诺淖x取和存儲(chǔ)其實(shí)都是對(duì)mmssms.db這個(gè)數(shù)據(jù)庫(kù)的操作過(guò)程。而且因?yàn)檫@個(gè)是共享的數(shù)據(jù)庫(kù),所以只能用ContentProvider這個(gè)組件去操作db。

          總之,想要研究彩信這塊(包括普通短信),你就必須的研究mmssms.db的操作方法,多多了解每個(gè)表對(duì)應(yīng)的哪個(gè)uri,每個(gè)uri能提供什么樣的操作,那些字段代表短信的那些屬性等。
          最后推薦個(gè)好用的sqlite查看工具:SQLite Database Browser。


          posted @ 2011-08-16 14:50 建華 閱讀(4540) | 評(píng)論 (2)編輯 收藏

          Activity的生命周期

          注意到在Activity的API中有大量的onXXXX形式的函數(shù)定義,除了我們前面用到的onCreate以外,還有onStart,onStop以及onPause等等。從字面上看,它們是一些事件回調(diào),那么次序又是如何的呢?其實(shí)這種事情,自己做個(gè)實(shí)驗(yàn)最明白不過(guò)了。在做這個(gè)實(shí)驗(yàn)之前,我們先得找到在Android中的Log是如何輸出的。

          顯然,我們要用的是android.util.log類(lèi),這個(gè)類(lèi)相當(dāng)?shù)暮?jiǎn)單易用,因?yàn)樗峁┑娜且恍╈o態(tài)方法:
          Log.v(String tag, String msg);        //VERBOSE
          Log.d(String tag, String msg);       //DEBUG    
          Log.i(String tag, String msg);        //INFO
          Log.w(String tag, String msg);     //WARN
          Log.e(String tag, String msg);      //ERROR
          前面的tag是由我們定義的一個(gè)標(biāo)識(shí),一般可以用“類(lèi)名_方法名“來(lái)定義。
          輸出的LOG信息,如果用Eclipse+ADT開(kāi)發(fā),在LogCat中就可以看到,否則用adb logcat也行,不過(guò)我是從來(lái)都依賴(lài)于IDE環(huán)境的。

          好了,現(xiàn)在我們修改前面的HelloThree代碼:
             public void onStart()
              
          {
                  
          super.onStart();
                  Log.v(TAG,
          "onStart");
              }

              
          public void onStop()
              
          {
                  
          super.onStop();
                  Log.v(TAG,
          "onStop");
              }

              
          public void onResume()
              
          {
                  
          super.onResume();
                  Log.v(TAG,
          "onResume");
              }

              
          public void onRestart()
              
          {
                  
          super.onRestart();
                  Log.v(TAG,
          "onReStart");
              }

              
          public void onPause()
              
          {
                  
          super.onPause();
                  Log.v(TAG,
          "onPause");
              }

              
          public void onDestroy()
              
          {
                  
          super.onDestroy();
                  Log.v(TAG,
          "onDestroy");
              }

              
          public void onFreeze(Bundle outState)
              
          {
                  
          super.onFreeze(outState);
                  Log.v(TAG,
          "onFreeze");
              }
          在HelloThreeB中也同樣增加這樣的代碼,編譯,運(yùn)行一下,從logcat中分析輸出的日志。
          在啟動(dòng)第一個(gè)界面Activity One時(shí),它的次序是:
          onCreate (ONE) - onStart (ONE) - onResume(ONE) 
          雖然是第一次啟動(dòng),也要走一遍這個(gè)resume事件。然后,我們點(diǎn)goto跳到第二個(gè)Activity Two中(前一個(gè)沒(méi)有關(guān)閉),這時(shí)走的次序是:
          onFreeze(ONE) - onPause(ONE) - onCreate(TWO) - onStart(TWO) - onResume(TWO) - onStop(ONE)
          說(shuō)明,第二個(gè)Activity Two在啟動(dòng)前,One會(huì)經(jīng)歷一個(gè):凍結(jié)、暫停的過(guò)程,在啟動(dòng)Two后,One才會(huì)被停止?
          然后,我們?cè)冱c(diǎn)back回到第一個(gè)界面,這時(shí)走的次序是:
          onPause(TWO) - onActivityResult(ONE) - onStart(ONE) - onRestart(ONE) - onResume(ONE) - onStop(TWO) - onDestroy(TWO)
          說(shuō)明,返回時(shí),Two沒(méi)有經(jīng)歷凍結(jié)就直接暫停了,在One接收參數(shù),重啟后,Two就停止并被銷(xiāo)毀了。
          最后,我們點(diǎn)一下Exit退出應(yīng)用,它的次序是:
          onPause(ONE) - onStop(ONE) - onDestroy(ONE)
          說(shuō)明如果我們用了finish的話,不會(huì)有freeze,但是仍會(huì)經(jīng)歷pause - stop才被銷(xiāo)毀。

          這里有點(diǎn)疑問(wèn)的是:為什么回來(lái)時(shí)先是Start才是Restart?可是文檔中的圖上畫(huà)的卻是先restart再start的啊?不過(guò),后面的表格中的描述好象是正確的,start后面總是跟著resume(如果是第一次)或者restart(如果原來(lái)被stop掉了,這種情況會(huì)在start與resume中插一個(gè)restart)。

          下面不跑例子了,看看文檔吧。

          1.Android用Activity Stack來(lái)管理多個(gè)Activity,所以呢,同一時(shí)刻只會(huì)有最頂上的那個(gè)Activity是處于active或者running狀態(tài)。其它的Activity都被壓在下面了。

          2.如果非活動(dòng)的Activity仍是可見(jiàn)的(即如果上面壓著的是一個(gè)非全屏的Activity或透明的Activity),它是處于paused狀態(tài)的。在系統(tǒng)內(nèi)存不足的情況下,paused狀態(tài)的Activity是有可被系統(tǒng)殺掉的。只是不明白,如果它被干掉了,界面上的顯示又會(huì)變成什么模樣?看來(lái)下回有必要研究一下這種情況了。

          3.幾個(gè)事件的配對(duì)可以比較清楚地理解它們的關(guān)系。Create與Destroy配成一對(duì),叫entrie lifetime,在創(chuàng)建時(shí)分配資源,則在銷(xiāo)毀時(shí)釋放資源;往上一點(diǎn)還有Start與Stop一對(duì),叫visible lifetime,表達(dá)的是可見(jiàn)與非可見(jiàn)這么一個(gè)過(guò)程;最頂上的就是Resume和Pause這一對(duì)了,叫foreground lifetime,表達(dá)的了是否處于激活狀態(tài)的過(guò)程。

          4.因此,我們實(shí)現(xiàn)的Activity派生類(lèi),要重載兩個(gè)重要的方法:onCreate()進(jìn)行初始化操作,onPause()保存當(dāng)前操作的結(jié)果。

          除了Activity Lifecycle以外,Android還有一個(gè)Process Lifecycle的說(shuō)明:

          在內(nèi)存不足的時(shí)候,Android是會(huì)主動(dòng)清理門(mén)戶的,那它又是如何判斷哪個(gè)process是可以清掉的呢?文檔中也提到了它的重要性排序:

          1.最容易被清掉的是empty process,空進(jìn)程是指那些沒(méi)有Activity與之綁定,也沒(méi)有任何應(yīng)用程序組件(如Services或者IntentReceiver)與之綁定的進(jìn)程,也就是說(shuō)在這個(gè)process中沒(méi)有任何activity或者service之類(lèi)的東西,它們僅僅是作為一個(gè)cache,在啟動(dòng)新的Activity時(shí)可以提高速度。它們是會(huì)被優(yōu)先清掉的。因此建議,我們的后臺(tái)操作,最好是作成Service的形式,也就是說(shuō)應(yīng)該在Activity中啟動(dòng)一個(gè)Service去執(zhí)行這些操作。

          2.接下來(lái)就是background activity了,也就是被stop掉了那些activity所處的process,那些不可見(jiàn)的Activity被清掉的確是安全的,系統(tǒng)維持著一個(gè)LRU列表,多個(gè)處于background的activity都在這里面,系統(tǒng)可以根據(jù)LRU列表判斷哪些activity是可以被清掉的,以及其中哪一個(gè)應(yīng)該是最先被清掉。不過(guò),文檔中提到在這個(gè)已被清掉的Activity又被重新創(chuàng)建的時(shí)候,它的onCreate會(huì)被調(diào)用,參數(shù)就是onFreeze時(shí)的那個(gè)Bundle。不過(guò)這里有一點(diǎn)不明白的是,難道這個(gè)Activity被killed時(shí),Android會(huì)幫它保留著這個(gè)Bundle嗎?

          3.然后就輪到service process了,這是一個(gè)與Service綁定的進(jìn)程,由startService方法啟動(dòng)。雖然它們不為用戶所見(jiàn),但一般是在處理一些長(zhǎng)時(shí)間的操作(例如MP3的播放),系統(tǒng)會(huì)保護(hù)它,除非真的沒(méi)有內(nèi)存可用了。

          4.接著又輪到那些visible activity了,或者說(shuō)visible process。前面也談到這個(gè)情況,被Paused的Activity也是有可能會(huì)被系統(tǒng)清掉,不過(guò)相對(duì)來(lái)說(shuō),它已經(jīng)是處于一個(gè)比較安全的位置了。

          5.最安全應(yīng)該就是那個(gè)foreground activity了,不到迫不得已它是不會(huì)被清掉的。這種process不僅包括resume之后的activity,也包括那些onReceiveIntent之后的IntentReceiver實(shí)例。

          在Android Application的生命周期的討論中,文檔也提到了一些需要注意的事項(xiàng):因?yàn)锳ndroid應(yīng)用程序的生存期并不是由應(yīng)用本身直接控制的,而是由Android系統(tǒng)平臺(tái)進(jìn)行管理的,所以,對(duì)于我們開(kāi)發(fā)者而言,需要了解不同的組件Activity、Service和IntentReceiver的生命,切記的是:如果組件的選擇不當(dāng),很有可能系統(tǒng)會(huì)殺掉一個(gè)正在進(jìn)行重要工作的進(jìn)程。

          posted @ 2011-08-03 15:41 建華 閱讀(231) | 評(píng)論 (0)編輯 收藏

          Eclipse+ADT進(jìn)行Android應(yīng)用程序的代碼混淆和簽名

          啟動(dòng)代碼混淆功能

          在較新版本的Android tools和ADT,項(xiàng)目工程里面是帶有proguard.cfg的代碼混淆配置文件,但默認(rèn)是沒(méi)有啟動(dòng)這個(gè)配置的,需要手動(dòng)地在default.properties里面添加指定這個(gè)配置文件:
          # Project target.
          target=android-3
          proguard.config=proguard.cfg
          然后按F5刷新當(dāng)前項(xiàng)目工程,這時(shí)候Eclipse檢測(cè)了文件的變動(dòng)而重新編譯!

          生成簽名發(fā)布apk

          以下圖片轉(zhuǎn)自http://jojol-zhou.iteye.com/blog/719428
          1.Eclipse工程中右鍵工程,彈出選項(xiàng)中選擇 android工具-生成簽名應(yīng)用包:
          右鍵選擇
          2.選擇需要打包的android項(xiàng)目工程(注:這里會(huì)自動(dòng)選擇當(dāng)前的Project的):
          3.如果已有私鑰文件,選擇私鑰文件 輸入密碼,如果沒(méi)有私鑰文件見(jiàn) 第6和7步創(chuàng)建私鑰文件:
          4.輸入私鑰別名和密碼:
          5.選擇APK存儲(chǔ)的位置,并完成設(shè)置 開(kāi)始生成:
          6.沒(méi)有私鑰文件的情況,創(chuàng)建私鑰文件(注:這里私鑰文件的Location位置最好自己選擇一個(gè)新位置,便于牢記,而且最好把這個(gè)私鑰文件備份到其他地方去以免丟失,因?yàn)閼?yīng)用程序的更新需要同一私鑰文件):
          7.輸入私鑰文件所需信息,并創(chuàng)建(注:這里的密碼是用于Key的別名的,和上面的KeyStore文件的不同,這點(diǎn)可以看步驟3和4。另外下面的名字,開(kāi)發(fā)者資料等是不需要全部填寫(xiě)的,dialog會(huì)有提示的):
          這時(shí)候生成的apk,我發(fā)現(xiàn)是比debug版本的要小!如果你發(fā)現(xiàn)沒(méi)有變小的話,請(qǐng)確認(rèn)項(xiàng)目工程是重新編譯的!但代碼混淆的效果一般般,基本上還是可以看到原來(lái)的語(yǔ)句!

          posted @ 2011-06-23 19:42 建華 閱讀(1026) | 評(píng)論 (0)編輯 收藏

          Android的Task和Activity相關(guān)

               摘要: android:allowTaskReparenting    用來(lái)標(biāo)記Activity能否從啟動(dòng)的Task移動(dòng)到有著affinity的Task(當(dāng)這個(gè)Task進(jìn)入到前臺(tái)時(shí))——“true”,表示能移動(dòng),“false”,表示它必須呆在啟動(dòng)時(shí)呆在的那個(gè)Task里。   ...  閱讀全文

          posted @ 2011-06-23 17:42 建華 閱讀(12468) | 評(píng)論 (0)編輯 收藏

          Android APK 簽名

          Apk簽名首先要有一個(gè)keystore的簽名用的文件.
          keystore是由jdk自帶的工具keytool生成的.具體生成方式參考一下:
          開(kāi)始->運(yùn)行->cmd->cd 到你安裝的jdk的目錄這里我是 C:\Program Files\Java\jdk1.6.0_10\bin
          然后輸入:keytool -genkey -alias asaiAndroid.keystore -keyalg RSA -validity 20000 -keystore asaiAndroid.keystore
          -alias 后跟的是別名這里是 asaiAndroid.keystore
          -keyalg 是加密方式這里是 RSA
          -validity 是有效期 這里是 20000
          -keystore 就是要生成的keystore的名稱(chēng) 這里是 asaiAndroid.keystore
          然后按回車(chē)
          按回車(chē)后首先會(huì)提示你輸入密碼:這個(gè)在簽名時(shí)要用的要記住了哦。
          然后會(huì)再確認(rèn)你的密碼。
          之后會(huì)依次叫你輸入 姓名,組織單位,組織名稱(chēng),城市區(qū)域,省份名稱(chēng),國(guó)家代碼等。
          參考:
           
          運(yùn)行完可以在 C:\Program Files\Java\jdk1.6.0_10\bin 里找到剛才生產(chǎn)的keyStore文件

          好現(xiàn)在開(kāi)始給Apk簽名了:
          在 C:\Program Files\Java\jdk1.6.0_10\bin 還提供一個(gè)工具 jarsigner.exe
          好現(xiàn)在可以在剛才的命令行后繼續(xù)運(yùn)行以下命令給APK簽名:
          jarsigner -verbose -keystore asaiAndroid.keystore -signedjar LotteryOnline_signed.apk LotteryOnline.apk asaiAndroid.keystore
          -keystore:keystore 的名稱(chēng)
          LotteryOnline_signed.apk  是簽完名后的APK
          LotteryOnline.apk 是簽名前的apk
          然后按回車(chē):會(huì)要求輸入剛才設(shè)置的密碼,輸入后按回車(chē)就開(kāi)始簽名了。
          參考:
           
          運(yùn)行成功后在 C:\Program Files\Java\jdk1.6.0_10\bin 目錄下會(huì)多出一個(gè)被簽名的apk文件,
          參考:
           

          posted @ 2011-06-23 17:40 建華 閱讀(834) | 評(píng)論 (0)編輯 收藏

          僅列出標(biāo)題
          共4頁(yè): 上一頁(yè) 1 2 3 4 下一頁(yè) 
          主站蜘蛛池模板: 梅州市| 遵义市| 长沙市| 崇礼县| 厦门市| 淅川县| 遵化市| 海阳市| 建水县| 阿拉善右旗| 陇南市| 鄂尔多斯市| 青神县| 涞水县| 赤壁市| 台前县| 天门市| 合川市| 天等县| 玉林市| 余庆县| 桓台县| 海伦市| 常熟市| 景泰县| 潞城市| 元阳县| 凤台县| 建阳市| 八宿县| 梅河口市| 射洪县| 永嘉县| 水富县| 甘南县| 仙桃市| 隆安县| 五家渠市| 仪征市| 铜鼓县| 茶陵县|