小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

[z]android 應(yīng)用程序Activity之間數(shù)據(jù)傳遞與共享的幾種途徑

 techres 2012-02-16

android 應(yīng)用程序Activity之間數(shù)據(jù)傳遞與共享的幾種途徑

分類: Android 1112人閱讀 評(píng)論(1) 收藏 舉報(bào)

1.基于消息的通信機(jī)制  Intent ---boudle ,extra

    數(shù)據(jù)類型有限,比如遇到不可序列化的數(shù)據(jù)Bitmap,InputStream, 或者LinkList鏈表等等數(shù)據(jù)類型就不太好用。

2. 利用static靜態(tài)數(shù)據(jù), public static成員變量;

3.基于外部存儲(chǔ)的傳輸,  File/Preference/ Sqlite ,如果要針對(duì)第三方應(yīng)用需要Content Provider 

4.基于IPC的通信機(jī)制

    context 與Service之間的傳輸,如Activity與Service之間的通信,定義AIDL接口文件。

   示例: http://www./thread-36249-1-1.html

5. 基于Application Context, 例子如下文:


    在當(dāng)前Activity將兩個(gè)值傳到了Test中。但如果遇到不可序列化的數(shù)據(jù),如Bitmap、InputStream等,intent就無(wú)能為力了。因此,我們很自然地會(huì)想到另外一種方法,靜態(tài)變量。如下面的代碼所示:


    public  class  Product  extends  Activity
   {
         public  static  Bitmap mBitmap;
          
   }


    對(duì)于上面的代碼來(lái)說(shuō),其他任何類可以直接使用Product中的mBitmap變量。這么做很easy、也很cool,但卻very very wrong。我們千萬(wàn)不要以為Davlik虛擬機(jī)的垃圾回收器會(huì)幫助我們回收不需要的內(nèi)存垃圾。事實(shí)上,回收器并不可靠,尤其是手機(jī)上,是更加的不可靠。 因此,除非我們要使自己的程序變得越來(lái)越糟糕,否則盡量遠(yuǎn)離static。

注:如果經(jīng)常使用static的Bitmap、Drawable等變量。可能就會(huì)拋出一個(gè)在Android系統(tǒng)中非常著名的異常(以前budget這個(gè)單詞一直記不住什么意思,自從經(jīng)常拋出這個(gè)異常后,這個(gè)單詞終于爛熟于心了, )

ERROR/AndroidRuntime(4958): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget


    如果不使用static,總得有方法來(lái)代替它(盡管我很喜歡public static,我相信很多人也喜歡它,但為了我們的程序,建議還是忍痛割愛(ài)吧),那么這個(gè)新的解決方案就是本文的主題,這就是Application Context,相當(dāng)于Web程序的Application,它的生命周期和應(yīng)用程序一樣長(zhǎng)(這個(gè)我喜歡)。

    那么現(xiàn)在來(lái)看看如何使用這個(gè)Application Context。我們可以通過(guò)Context.getApplicationContext或Context.getApplication方法獲得 Application Context。但要注意,我們獲得的只是Context對(duì)象,而更理想的方法是獲得一個(gè)類的對(duì)象。ok,說(shuō)干就干,下面來(lái)定義一個(gè)類。


package  net.blogjava.mobile1;

import  android.app.Application;
import  android.graphics.Bitmap;

public  class  MyApp  extends  Application
{
     private  Bitmap mBitmap;

     public  Bitmap getBitmap()
    {
         return  mBitmap;
    }

     public  void  setBitmap(Bitmap bitmap)
    {
         this .mBitmap  =  bitmap;
    }
    
}


    上面這個(gè)類和普通的類沒(méi)什么本質(zhì)的不同。但該類是Application的子類。對(duì)了,這就是使用Application Context的第一步,定義一個(gè)繼承自Application的類。然后呢,就在這個(gè)類中定義任何我們想使其全局存在的變量了,如本例中的 Bitmap。下面還需要一個(gè)重要的步驟,就是在<application>標(biāo)簽中使用android:name屬性來(lái)指定這個(gè)類,代碼如 下:


< application  android:name =".MyApp"  android:icon ="@drawable/icon"  android:label ="@string/app_name" > 
 
</ application?


    接下來(lái)的最后一步就是向MyApp對(duì)象中存入Bitmap對(duì)象,或從MyApp對(duì)象中取出Bitmap對(duì)象了,存入Bitmap對(duì)象的代碼如下:


    MyApp myApp  =  (MyApp)getApplication();
        
    Bitmap bitmap  =  BitmapFactory.decodeResource( this .getResources(), R.drawable.icon);
        
    myApp.setBitmap(bitmap);

    獲得Bitmap對(duì)象的代碼:

    ImageView imageview  =  (ImageView)findViewById(R.id.ivImageView);
        
    MyApp myApp  =  (MyApp)getApplication();
        
    imageview.setImageBitmap(myApp.getBitmap()); 
    
    上面兩段代碼可以在任何的Service、Activity中使用。全局的。

參考:

1.http:///?p=229

2.http://blog.csdn.net/nokiaguy/archive/2010/11/10/5998986.aspx

轉(zhuǎn)載自:http://blog.csdn.net/kieven2008/archive/2010/11/13/6006905.aspx

 

一、基于消息的通信機(jī)制 Intent ---boudle ,extra
Android為了屏蔽進(jìn)程的概念,利用不同的組件[Activity、Service]來(lái)表示進(jìn)程之間的通信!
組件間通信的核心機(jī)制是Intent,通過(guò)Intent可以開(kāi)啟一個(gè)Activity或Service,不論這個(gè)Activity或Service是屬于當(dāng)前應(yīng)用還是其它應(yīng)用的!
                                                                 
Intent包含兩部分:
1、目的[action]--要往哪里去
2、內(nèi)容[category、data]--路上帶了些啥,區(qū)分性數(shù)據(jù)或內(nèi)容性數(shù)據(jù)

Intent類型:
1、顯式--直接指定消息目的地,只適合同一進(jìn)程內(nèi)的不同組件之間通信
new Intent(this,Target.class)
2、隱式--AndroidMainifest.xml中注冊(cè),一般用于跨進(jìn)程通信
new Intent(String action)

實(shí)現(xiàn)-Intent簡(jiǎn)單進(jìn)程間通信
顯式的Intent較為簡(jiǎn)單!

如何實(shí)現(xiàn)隱式Intent呢?
在AndroidManifest.xml文件中定義<activity>
說(shuō)明:
1、一個(gè)<activity>包括:
零個(gè)或多個(gè)<intent-filter>

它主要是作為匹配的標(biāo)準(zhǔn),能否匹配成功由<action>、<category>、<data>三個(gè)tag共同決定的。

2、一個(gè)<intent-filter>包括:
一個(gè)或多個(gè) <action>
零個(gè)或多個(gè) <category> 
指定<activity>的分類特征
eg:
<category android:name="android.intent.category.LAUNCHER" />
--說(shuō)明該<activity>是該project運(yùn)行的第一個(gè)界面

<category android:name="android.intent.category.HOME" />
--說(shuō)明該<activity>可以作為L(zhǎng)auncher的,即系統(tǒng)操作界面

<category android:name="android.intent.category.DEFAULT" />
--缺省情況

零個(gè)或一個(gè) <data> 
-- 指定攜帶的數(shù)據(jù)的類型,使用MIME類型描述方式來(lái)描述
eg:
<data android:mimeType="video/mpeg" />
video/mpeg表示編碼格式為mpeg的視頻,
也可以使用通配符video/*表示任意格式的視頻文件類型;

在查詢ContentProvider時(shí),可以使用
<data android:mimeType="vnd.android.cursor.dir/vnd.myq.note" />
查詢上來(lái)的數(shù)據(jù)是多個(gè)記錄
<data android:mimeType="vnd.android.cursor.item/vnd.myq.note" />
查詢上來(lái)的數(shù)據(jù)是單個(gè)記錄
如上設(shè)置,要重寫(xiě)SQLiteOpenHelper的getType(Uri uri)方法
eg:
@Override
public String getType(Uri uri) {
  final int match = sUriMatcher.match(uri) ;
  switch(match)
  {
  case NOTES :
  case LIVE_FOLDER_NOTES:
   return "vnd.android.cursor.dir/vnd.myq.note" ;
   
  case NOTES_ID :
   return "vnd.android.cursor.item/vnd.myq.note" ;
   
  default:
   throw new IllegalArgumentException("invalid uri : " + uri) ;
  }
}

數(shù)據(jù)的URI由scheme(協(xié)議),host,port,path四部分:scheme://host:port/path
<data android:scheme="http://localhost:8080/test.jsp" />

3、一個(gè)Intent對(duì)應(yīng)多種匹配結(jié)果的處理說(shuō)明
一個(gè)intent有多個(gè)可匹配的處理組件,系統(tǒng)如何處理?
分響應(yīng)消息的組件類型:
1)如果是service那么這些service都可以啟動(dòng)并處理消息。
2)如果是Activity則會(huì)彈出一個(gè)對(duì)話框讓用戶進(jìn)行選擇。

4、安全性問(wèn)題
如果不同進(jìn)程間的組件可以通過(guò)隱式消息互相通信,那程序不是可以輕易調(diào)用到其他的程序或者系統(tǒng)中的一些敏感程序的組件,這樣會(huì)不會(huì)很不安全呢?
其實(shí)Android在安全方面有一個(gè)統(tǒng)一,完備和輕便的安全策略模型。

簡(jiǎn)單一點(diǎn)說(shuō)就是:權(quán)限設(shè)置問(wèn)題
我們可以自己定義permission,然后在需要的組件處設(shè)置該permission,那么用戶要想該組件,必須要配置該permission,否則訪問(wèn)失敗的!

eg:
1、定義permission
<permission-group android:name="android.permission-group.MYQ_INFO"/> 
<permission
     android:name="com.myq.android.permission.DATETIME_SERVICE"
     android:permissionGroup="android.permission-group.MYQ_INFO"
     android:protectionLevel="normal"
     />

2、配置permission
<service android:name=".DateTimeService" android:permission="com.myq.android.permission.DATETIME_SERVICE">
   <intent-filter>
<action android:name="com.myq.android.MultiProcessTest.DATETIMESERVICE_ACTION" />
   </intent-filter>
</service>

3、使用permission
<uses-permission android:name="com.myq.android.permission.DATETIME_SERVICE"/>

二.基于IPC的通信機(jī)制
有了Intent這種基于消息的進(jìn)程內(nèi)或進(jìn)程間通信模型,我們就可以通過(guò)Intent去開(kāi)啟一個(gè)Service,可以通過(guò)Intent跳轉(zhuǎn)到另一個(gè)Activity,不論上面的Service或Activity是在當(dāng)前進(jìn)程還是其它進(jìn)程內(nèi)即不論是當(dāng)前應(yīng)用還是其它應(yīng)用的Service或Activity,通過(guò)消息機(jī)制都可以進(jìn)行通信!

但是通過(guò)消息機(jī)制實(shí)現(xiàn)的進(jìn)程間通信,有一個(gè)弊端就是,如果我們的Activity與Service之間的交往不是簡(jiǎn)單的Activity開(kāi)啟Service操作,而是要隨時(shí)發(fā)一些控制請(qǐng)求,那么必須就要保證Activity在Service的運(yùn)行過(guò)程中隨時(shí)可以連接到Service。

eg:音樂(lè)播放程序
后臺(tái)的播放服務(wù)往往獨(dú)立運(yùn)行,以方便在使用其他程序界面時(shí)也能聽(tīng)到音樂(lè)。同時(shí)這個(gè)后臺(tái)播放服務(wù)也會(huì)定義一個(gè)控制接口,比如播放,暫停,快進(jìn)等方法,任何時(shí)候播放程序的界面都可以連接到播放服務(wù),然后通過(guò)這組控制接口方法對(duì)其控制。

如上的需求僅僅通過(guò)Intent去開(kāi)啟Service就無(wú)法滿足了!從而Android的顯得稍微笨重的IPC機(jī)制就出現(xiàn)了,然而它的出現(xiàn)只適用于Activity與Service之間的通信,類似于遠(yuǎn)程方法調(diào)用,就像是C/S模式的訪問(wèn),通過(guò)定義AIDL接口文件來(lái)定義一個(gè)IPC接口,Server端實(shí)現(xiàn)IPC接口,Client端調(diào)用IPC接口的本地代理。

由于IPC調(diào)用是同步的,如果一個(gè)IPC服務(wù)需要超過(guò)幾毫秒的時(shí)間才能完成的話,你應(yīng)該避免在Activity的主線程中調(diào)用,否則IPC調(diào)用會(huì)掛起應(yīng)用程序?qū)е陆缑媸ロ憫?yīng)。在 這種情況下,應(yīng)該考慮單起一個(gè)線程來(lái)處理IPC訪問(wèn)。

兩個(gè)進(jìn)程間IPC看起來(lái)就象是一個(gè)進(jìn)程進(jìn)入另一個(gè)進(jìn)程執(zhí)行代碼然后帶著執(zhí)行的結(jié)果返回。

IPC機(jī)制鼓勵(lì)我們“盡量利用已有功能,利用IPC和包含已有功能的程序協(xié)作完成一個(gè)完整的項(xiàng)目”

IPC實(shí)現(xiàn)demo:
我的
project -- MultiProcessTest
package -- com.myq.android.MultiProcessTest

1、AIDL文件,我是放在package下,
文件名稱為:
IDateTimeService.aidl
文件內(nèi)容為:
package com.myq.android.MultiProcessTest ;
interface IDateTimeService 
{
String getCurrentDateTime(in String format) ;
}

如果正確配置,會(huì)在gen下,生成同名的java文件
簡(jiǎn)單摘要:
//我們需要實(shí)現(xiàn)的類Stub
public interface IDateTimeService extends android.os.IInterface
{
...
public static abstract class Stub
extends android.os.Binder
implements com.myq.android.MultiProcessTest.IDateTimeService
{
...
//獲取實(shí)例的方法asInterface
public static com.myq.android.MultiProcessTest.IDateTimeService asInterface(android.os.IBinder obj)
{
  ...
}
...
}
//我們自己的業(yè)務(wù)方法,需要實(shí)現(xiàn)的
public java.lang.String getCurrentDateTime(java.lang.String format) throws android.os.RemoteException;
}

2、Service中實(shí)現(xiàn)IDateTimeService.Stub
eg:
package com.myq.android.MultiProcessTest;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

public class DateTimeService extends Service {

public static final String DATETIME_SERVICE_ACTION = "com.myq.android.MultiProcessTest.DATETIMESERVICE_ACTION" ;

private static final String TAG = "--------DateTimeService-------" ;

private  SimpleDateFormat sdf ;

private final IDateTimeService.Stub stub = new IDateTimeService.Stub()
{
  
  public String getCurrentDateTime(String format) throws RemoteException {
   return getCurrentDateTimeString(format) ;
  }
} ;

private synchronized String getCurrentDateTimeString(String format)
{
     sdf = new SimpleDateFormat(format) ;
     final String temp = sdf.format(new Date()) ;
   Log.i(TAG,"getCurrentDateTimeString--" + Thread.currentThread() + "--" + temp) ;
   return temp ;
}

public IBinder onBind(Intent arg0) 
{
  Log.i(TAG, "onBind--" + Thread.currentThread()) ;
  return stub;
}
}

3、Client端代碼實(shí)現(xiàn)
private ServiceConnection mServiceConn = new ServiceConnection()
{
  
  public void onServiceConnected(ComponentName name, IBinder service) {
   mDateTimeService = IDateTimeService.Stub.asInterface(service) ;
  }
  
  public void onServiceDisconnected(ComponentName name) {
   mDateTimeService = null ;
  }
} ;

說(shuō)明:
網(wǎng)上的好多資料都沒(méi)有涉及IPC調(diào)用的AIDL的具體說(shuō)明!
它本質(zhì)上是Server端和Client端都具有相同的AIDL文件,要位于相同的包下,即package的包名藥一樣,然后才能正確的通過(guò)proxy訪問(wèn),否則client與server的aidl文件處于不同package會(huì)出錯(cuò)的。

aidl模型如下:
                |<--------------------aidl---------------------->|
client端-->proxy  ----------parcel數(shù)據(jù)包-------- stub<---server端
從而proxy+parcel+stub構(gòu)成了aidl.
只不過(guò),proxy運(yùn)行在客戶進(jìn)程,而stub運(yùn)行在服務(wù)端進(jìn)程。
當(dāng)你通過(guò)aidl去訪問(wèn)服務(wù)端時(shí),客戶端會(huì)阻塞在proxy,服務(wù)端處理完后,通知proxy返回。

四、附件及說(shuō)明
1、
附件是我測(cè)試所用的demo,我用的系統(tǒng)是ubuntu9,Android2.2版本
基本功能:
可以根據(jù)用戶選擇的不同輸出格式輸出當(dāng)前系統(tǒng)的時(shí)間。
2、
運(yùn)行順序:
先運(yùn)行Server端:MultiProcessTest
再運(yùn)行Client端:MultiProcessTestClient

3、
注意點(diǎn):
Server和Client端的AIDL文件必須要位于同package下,否則會(huì)出錯(cuò)
安全性問(wèn)題實(shí)現(xiàn),權(quán)限控制--定義、配置、使用
異步處理問(wèn)題--Handler

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多