|
方法一: Java代碼  - public void saveIcon(Bitmap icon) {
- if (icon == null) {
- return;
- }
-
- // 最終圖標(biāo)要保存到瀏覽器的內(nèi)部數(shù)據(jù)庫(kù)中,系統(tǒng)程序均保存為SQLite格式,Browser也不例外,因?yàn)閳D片是二進(jìn)制的所以使用字節(jié)數(shù)組存儲(chǔ)數(shù)據(jù)庫(kù)的
- // BLOB類(lèi)型
- final ByteArrayOutputStream os = new ByteArrayOutputStream();
- // 將Bitmap壓縮成PNG編碼,質(zhì)量為100%存儲(chǔ)
- icon.compress(Bitmap.CompressFormat.PNG, 100, os);
- // 構(gòu)造SQLite的Content對(duì)象,這里也可以使用raw
- ContentValues values = new ContentValues();
- // 寫(xiě)入數(shù)據(jù)庫(kù)的Browser.BookmarkColumns.TOUCH_ICON字段
- values.put(Browser.BookmarkColumns.TOUCH_ICON, os.toByteArray());
-
- DBUtil.update(....);//調(diào)用更新或者插入到數(shù)據(jù)庫(kù)的方法
- }
方法二:如果數(shù)據(jù)表入口時(shí)一個(gè)content:URI Java代碼  - import android.provider.MediaStore.Images.Media;
- import android.content.ContentValues;
- import java.io.OutputStream;
-
- // Save the name and description of an image in a ContentValues map.
- ContentValues values = new ContentValues(3);
- values.put(Media.DISPLAY_NAME, "road_trip_1");
- values.put(Media.DESCRIPTION, "Day 1, trip to Los Angeles");
- values.put(Media.MIME_TYPE, "image/jpeg");
-
- // Add a new record without the bitmap, but with the values just set.
- // insert() returns the URI of the new record.
- Uri uri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);
-
- // Now get a handle to the file for that record, and save the data into it.
- // Here, sourceBitmap is a Bitmap object representing the file to save to the database.
- try {
- OutputStream outStream = getContentResolver().openOutputStream(uri);
- sourceBitmap.compress(Bitmap.CompressFormat.JPEG, 50, outStream);
- outStream.close();
- } catch (Exception e) {
- Log.e(TAG, "exception while writing image", e);
- }
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)
原文出自: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
建一個(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,我又邪惡了,呵呵!
摘要: 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è)參... 閱讀全文
最近有個(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。
注意到在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)程。
啟動(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ā)布apk1.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ǔ)句!
摘要: 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里。 ... 閱讀全文
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文件, 參考:
|