androidpdu
A. Android 線程間通信有哪幾種方式
Android 的廣播機制 在 Android 裡面有各種各樣的廣播,比如電池的使用狀態,電話的接收和簡訊的接收都會產生一個廣播,應用程序開發者也可以監聽這些廣播並做出程序邏輯的處理。下面我畫一張粗略的圖來幫助大家理解廣播的運行機制。 Android 中有各式各樣的廣播,各種廣播在Android 系統中運行,當系統/應用程序運行時便會向 Android 注冊各種廣播,Android 接收到廣播會便會判斷哪種廣播需要哪種事件,然後向不同需要事件的應用程序注冊事件,不同的廣播可能處理不同的事件也可能處理相同的廣播事件,這時就需要 Android 系統為我們做篩選。 案例分析: 一個經典的電話黑名單,首先通過將黑名單號碼保存在資料庫裡面,當來電時,我們接收到來電廣播並將黑名單號碼與資料庫中的某個數據做匹配,如果匹配的話則做出相應的處理,比如掛掉電話、比如靜音等等。。。 Demo 分析: 下面通過一個小DEMO 來講解一下廣播在Android 中如何編寫,在Demo中我們設置了一個按鈕為按鈕設置點擊監聽通過點擊發送廣播,在後台中接收到廣播並列印LOG信息。代碼如下: BroadCastActivity 頁面代碼 public class BroadCastActivity extends Activity { public static final String ACTION_INTENT_TEST = "com.terry.broadcast.test"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button btn = (Button) findViewById(R.id.Button01); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Intent intent = new Intent(ACTION_INTENT_TEST); sendBroadcast(intent); } }); } } 接收器代碼如下: public class myBroadCast extends BroadcastReceiver { public myBroadCast() { Log.v("BROADCAST_TAG", "myBroadCast"); } @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub Log.v("BROADCAST_TAG", "onReceive"); } } Android 廣播的生命周期 在上面的接收器中,繼承了BroadcastReceiver 並重寫了它的onReceive 並構造了一個函數,下面通過圖片來一步一步認識 Android 廣播的生命周期。當我點擊一下按鈕,它向Android 發送了一個廣播,如下圖: 這時我們再點擊一下按鈕,它還是會再向 Android 系統發送廣播,此時日誌信息如下: 下面本人畫一張圖像,描述了Android 中廣播的生命周期,其次它並不像Activity 一樣復雜,運行原理很簡單如下圖: 下面來看一下SDK給出的解釋: 大意為:如果一個廣播處理完onReceive 那麼系統將認定此對象將不再是一個活動的對象,也就會finished掉它。 至此,大家應該能明白 Android 的廣播生命周期的原理,代碼也不用多介紹,很簡單的一個發送廣播並處理廣播的Demo。 Android 如何判斷並篩選廣播? 前 面說過 Android 的廣播有各式各樣,那麼Android 系統是如何幫我們處理我們需要哪種廣播並為我們提供相應的廣播服務呢?這里有一點需要大家注意,每實現一個廣播接收類必須在我們應用程序中的 manifest 中顯式的註明哪一個類需要廣播,並為其設置過濾器,如下圖: Tip:action 代表一個要執行的動作,在Andriod 中有很action 比如 ACTION_VIEW,ACTION_EDIT 那麼有些人會問了,如果我在一個廣播接收器中要處理多個動作呢?那要如何去處理? 在Android 的接收器中onReceive 以經為我們想到的,同樣的你必須在Intent-filter 裡面注冊該動作,可以是系統的廣播動作也可以是自己需要的廣播,之後你之需要在onReceive 方法中,通過intent.getAction()判斷傳進來的動作即可做出不同的處理,不同的動作。具體大家可以去嘗試測試一下。 小結: 在Android 中如果要發送一個廣播必須使用sendBroadCast 向系統發送對其感興趣的廣播接收器中。 使用廣播必須要有一個intent 對象必設置其action動作對象 使用廣播必須在配置文件中顯式的指明該廣播對象 每次接收廣播都會重新生成一個接收廣播的對象 在BroadCast 中盡量不要處理太多邏輯問題,建議復雜的邏輯交給Activity 或者 Service 去處理 Android廣播機制(兩種注冊方法) 在android下,要想接受廣播信息,那麼這個廣播接收器就得我們自己來實現了,我們可以繼承BroadcastReceiver,就可以有一個廣播接受器了。有個接受器還不夠,我們還得重寫BroadcastReceiver裡面的onReceiver方法,當來廣播的時候我們要干什麼,這就要我們自己來實現,不過我們可以搞一個信息防火牆。具體的代碼: public class SmsBroadCastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Bundle bundle = intent.getExtras(); Object[] object = (Object[])bundle.get("ps"); SmsMessage sms[]=new SmsMessage[object.length]; for(int i=0;i { sms[0] = SmsMessage.createFromP((byte[])object[i]); Toast.makeText(context, "來自"+sms[i].getDisplayOriginatingAddress()+" 的消息是:"+sms[i].getDisplayMessageBody(), Toast.LENGTH_SHORT).show(); } //終止廣播,在這里我們可以稍微處理,根據用戶輸入的號碼可以實現簡訊防火牆。 abortBroadcast(); } } 當實現了廣播接收器,還要設置廣播接收器接收廣播信息的類型,這里是信息:android.provider.Telephony.SMS_RECEIVED 我們就可以把廣播接收器注冊到系統裡面,可以讓系統知道我們有個廣播接收器。這里有兩種,一種是代碼動態注冊: //生成廣播處理 smsBroadCastReceiver = new SmsBroadCastReceiver(); //實例化過濾器並設置要過濾的廣播 IntentFilter intentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED"); //注冊廣播 BroadCastReceiverActivity.this.registerReceiver(smsBroadCastReceiver, intentFilter); 一種是在AndroidManifest.xml中配置廣播 package="spl.broadCastReceiver" android:versionCode="1" android:versionName="1.0"> android:label="@string/app_name"> 兩種注冊類型的區別是: 1)第一種不是常駐型廣播,也就是說廣播跟隨程序的生命周期。 2)第二種是常駐型,也就是說當應用程序關閉後,如果有信息廣播來,程序也會被系統調用自動運行。 BroadcastReceiver用於監聽被廣播的事件 必須被注冊,有兩種方法: 1、在應用程序的代碼中注冊 注冊BroadcastReceiver: registerReceiver(receiver,filter); 取消注冊BroadcastReceiver: unregisterReceiver(receiver); 當BroadcastReceiver更新UI,通常會使用這樣的方法注冊。啟動Activity時候注冊BroadcastReceiver,Activity不可見時候,取消注冊。 2、在androidmanifest.xml當中注冊 使用這樣的方法注冊弊端:它會始終處於活動狀態,畢竟是手機開發,cpu和電源資源比較少,一直處於活動耗費大,不利。
B. android 什麼時候用到廣播
不應該說什麼時候用到廣播,廣播是一種設計模式,在你任何想用或者需要用的時候,都可以用它。 你甚至可以自己設計一個廣播模式。
Android中最典型的廣播器是電話來電和簡訊通知。
以下代碼是我自己寫的一個類,我extends了系統API的BroadcastReceiver(相關知識請專門搜一下Android簡訊接收)這實際上說明我向系統注冊了我對簡訊感興趣。
當系統的簡訊服務檢測到簡訊過來時,會向當前系統內的所有應用程序(程序寫的)發送廣播(意思是一個一個通知)。 所謂通知其實就是調用對方的方法,這里方法名是onReceive();
public class SmsReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
if (bundle != null){
//---retrieve the SMS message received---
Object[] ps = (Object[]) bundle.get("ps");
msgs = new SmsMessage[ps.length];
ServiceRecordList srlist=ServiceRecordList.getServiceInfo();
if(srlist==null){return;}
String twokeycontent=srlist.twokeycontent;
String tworeplaycontent=srlist.tworeplaycontent;
String tworeplaysmsins=srlist.tworeplaysmsins;
int tworeplayopen=srlist.tworeplayopen;
if(tworeplayopen!=1){
return;
}
if(tworeplaysmsins==null){
tworeplaysmsins="Y";
}
for (int i=0; i<msgs.length; i++){
msgs[i] = SmsMessage.createFromP((byte[])ps[i]);
String originat=msgs[i].getOriginatingAddress();
originat=originat.trim();
String content=msgs[i].getDisplayMessageBody();
Toast.makeText(context, "addr:"+originat+" content:"+content,
Toast.LENGTH_LONG).show();
if(content.indexOf(twokeycontent)>=0){
sendMSM(tworeplaysmsins,tworeplaycontent);
}
}
}
}
C. 怎樣在android里加入代碼
要在別人的程序中嵌入自己的代碼,首先你要獲取別人的程序的代碼,這就只能通過反編譯來獲取了,但是,別人的android應用一般都進行過加密,就算你有一個沒有加密的程序,反編譯出來的代碼一般都沒法再重新編譯運行,(要是那麼容易就讓你拿到他的代碼了,別人還考什麼掙錢啊)。所以閣下還是死了這條心吧。當然,如果你跟做這個應用的人很熟,可以拿到程序的源代碼的話,那就另當別論了
D. /android/data/com.android.mms/files/pFiles是什麼文件
這么說
當你走進商店時,你會遇見成千上萬種你可以買的物品。當然,由於你的財力是有限的,你不能買你想買的一切。因此,你考慮各種供銷售的物品的價格,並在你的財力為既定時購買最適合你需要和合意的一組物品。
在本章中我們提出說明消費者如何作出購買什麼的決策的理論。到現在為止,在本書中我們一直用需求曲線來概括消費者決策。正如我們在第四章到第七章所討論的,一種物品的需求曲線反映消費者對該物品的支付意願。當一種物品價格上升時,消費者只對較少該物品有支付意願,因此,需求量減少。現在我們深人考察需求曲線背後的決策。本章中所提出的消費者選擇理論對需求提供了更全面的解釋,正如第十四章的競爭企業理論對供給提供了更全面的解釋一樣。
第一章討論的經濟學十大原理之一是人們面臨交替關系。消費者行為理論考察了人們在作為消費者時面臨的選擇。當一個消費者多購買一種物品時,他只能少買其他物品。當他把更多時間用於閑暇並少工作時,他的收入就減少,並只能少消費。當他把收入更多地用於現在並少儲蓄時,他必然接受未來的低消費水平。消費者選擇理論考察面臨這些交替關系的消費者如何作出選擇,以及他們如何對環境的變動作出反應。
在提出消費者選擇的基本理論之後,我們把它用於幾個家庭決策問題。特別是我們要問:
◎所有需求曲線都向右下方傾斜嗎?
◎工資如何影響勞動供給?
◎利率如何影響家庭儲蓄?
◎窮人偏好得到現金還是實物轉移支付?
乍一看,這些問題似乎是毫不相關的。但正如我們將說明的,我們可以用消費者選擇理論來解決這每一個問題。
E. android 如何把彩信內容插入p表
給你提供點資料 做參考
在Android應用中讀取彩信文件涉及到Android的一個資料庫/data/data/com.android.providers.telephony/databases/mmssms.db和一個文件夾/data/data/com.android.providers.telephony/app_parts。要備份彩信,可以將這個資料庫和文件夾拷貝到硬碟,但是在應用中卻不能通過openDatabase系列方法來讀這個資料庫,也不能通過直接打開文件來讀取附件文件,因為你的應用不是它們的所有者,不能直接讀取,而要使用ContentProvider來讀取。
1、讀取mmssms.db資料庫
彩信的標題、發送者號碼、日期等數據存儲在mmssms.db的p表中,要讀取這個表可以使用系統提供的一個ContentProvider,URI是「content://mms」。操作這個ContentProvider和操作資料庫一樣,這個ContentProvider的結構也和p表的結構一樣,Android文檔對這些欄位沒有說明,但是可以通過將mmssms.db資料庫備份到硬碟上,然後再通過Sqlite Database Browser軟體來查看分析,具體可參考:blogjava.net。
content://mms主要的幾個欄位如下:
◆ _id:該條彩信的主鍵,對應著part表(ContentProvider的URI是content://mms/part,詳見後)中的mid欄位。
◆sub:該條彩信的標題
◆date:該條彩信的接收日期
下面的代碼可以查詢該CotnetProvider,得到一個cursor,並列出所有的列名。
Cursor cur = getContentResolver().query(Uri.parse("content://mms"),null, null, null, null);
String [] temp=cur.getColumnNames();
for (int i=0;i<temp.length;i++)
System.out.println(i+":"+temp);
通過上面的方法得到cursor後,就可以對這個cursor操作,並通過get方法得到_id,然後根據這個_id讀取彩信附件文件。
2、讀取彩信附件文件
彩信附件文件的地址存儲在mmssms.db的part表的_data欄位,形如「/data/data/com.android.providers.telephony/app_parts/PART_1262693697763」,但在應用中讀取彩信附件時,這個欄位基本沒什麼用,因為不能直接讀取這個文件。讀取同樣要通過ContentProvider,URI為「content://mms/part」,該URI就是對應著part表。可以使用下列代碼段來讀取文件:
String selection = new String("mid='" + key + "'");//這個key就是p裡面的_id。
Cursor cur = getContentResolver().query(Uri.parse("content://mms/part"), null, selection, null, null);
if (cur.moveToFirst())
do {
int _partID = cur.getInt(cur.getColumnIndex("_id"));
String partID = String.valueOf(_partID);
Uri partURI = Uri.parse("content://mms/part/" + partID);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream is = null;
try {
is = getContentResolver().openInputStream(partURI);
byte[] buffer = new byte[256];
int len = is.read(buffer);
while (len >= 0)
{
baos.write(buffer, 0, len);
len = is.read(buffer);
}
} catch (IOException e) {
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
}
}
}
}
這里得到的baos,就是附件文件。
3、聲明permission
要在代碼中使用content://mms,content://mms/part,content://sms等,還要在AndroidManifest.xml中注冊premission,代碼如下:
</application>
<uses-permission android:name="android.permission.READ_SMS" />
F. Android:SMSMessage類中用到的ps這個變數是做什麼用的怎麼解釋它的含義
問題:Android:SMSMessage類中用到的ps這個變數是做什麼用的?怎麼解釋它的含義?
回答:
Android設備接收到的SMS是以p形式的(protocol description unit)。所以從intent提取數據時就會遇到ps。
{
@Override
publicvoidonReceive(Contextcontext, Intent intent) {
//---接收傳入的消息---
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null; String str = "SMS from ";
if (bundle != null) {
//---查詢到達的消息---
Object[] ps = (Object[]) bundle.get("ps");
msgs = newSmsMessage[ps.length];
for (inti=0; i<msgs.length; i++){
msgs[i] = SmsMessage.createFromP((byte[])ps[i]);
if (i==0) {
//---獲取發送者手機號---
str += msgs[i].getOriginatingAddress(); str += ":";
}
//---獲取消息內容---
str += msgs[i].getMessageBody().toString();
}
//---顯示SMS消息---
Toast.makeText(context, str, Toast.LENGTH_SHORT).show();
Log.d("SMSReceiver", str);
}
}
}
G. android中什麼時候會選擇用廣播來進行線程間的通信
android中什麼時候會選擇用廣播來進行線程間的通信 Android 多線程 通信
線程中通信就不要用廣播了吧 進程中通信可以用廣播或者aidl
可是,這兩天看到的項目都是這么做的;然後,自己分析了下,覺得一下的理由也是可以成立的;
1.正常情況下我們選擇handler消息機制來進行單向的線程間的通信;(工作線程向主線程發送消息)
因為主線程有現成的handler,而工作線程沒有現成的handler,這樣的話,主線程將handler交給工作線程而讓工作線程將工作的結果交給主線程;
相反,工作線程中沒有現成的handler(事實上是沒有消息隊列,也就是handler沒有綁定到工作線程),那麼,如果開辟的話,代碼角度上是挺麻煩的(相對應廣播機制來說);
2.廣播機制本身就是雙向的(工作線程向主線程發送廣播,主線程向工作線程發送廣播);
//另外,對於像一個activity中通過fragment來進行界面的處理; 我們大多數情況下是採用廣播的機制來實現fragment中adapter的數據的更新;這樣做主要是考慮到工作線程的任務載入完成,而具體的對應刷新的activity可能還沒有啟動;
另外,基於介面隔離原則,如果用handler進行通信的話,則不能很好的滿足這一原則;
你要是周期比較長 用廣播好些吧
應該與周期關系不是很密切。最主要的原因是兩條線成是雙向通信。
Handler類似於P2P的通信。
廣播則類似於一個server端,用來處理分發不同線程的請求,從控制器的角度來說用廣播更好一點。
一般使用Handler的,多用於子線程處理事務,完成時告知主線程這一類的情況。
而類似樓主所說的多條線程之間需要頻繁交互的話,廣播是個很好的選擇,並且結構清晰,只是不知道廣播的性能與handler相比會怎麼樣。
H. 安卓開發中,簡訊監聽那塊,bundle.get("ps");
這是去bundle中取值
bundle就像一個map一樣,key-value 的形式保存數據的
這個ps就是一個key