日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

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

 techres 2012-02-16

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

分類: Android 1112人閱讀 評論(1) 收藏 舉報

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

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

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

3.基于外部存儲的傳輸,  File/Preference/ Sqlite ,如果要針對第三方應用需要Content Provider 

4.基于IPC的通信機制

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

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

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


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


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


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

注:如果經(jīng)常使用static的Bitmap、Drawable等變量??赡芫蜁伋鲆粋€在Android系統(tǒng)中非常著名的異常(以前budget這個單詞一直記不住什么意思,自從經(jīng)常拋出這個異常后,這個單詞終于爛熟于心了, )

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


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

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


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;
    }
    
}


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


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


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


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

    獲得Bitmap對象的代碼:

    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

 

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

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

實現(xiàn)-Intent簡單進程間通信
顯式的Intent較為簡單!

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

它主要是作為匹配的標準,能否匹配成功由<action>、<category>、<data>三個tag共同決定的。

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

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

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

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

在查詢ContentProvider時,可以使用
<data android:mimeType="vnd.android.cursor.dir/vnd.myq.note" />
查詢上來的數(shù)據(jù)是多個記錄
<data android:mimeType="vnd.android.cursor.item/vnd.myq.note" />
查詢上來的數(shù)據(jù)是單個記錄
如上設置,要重寫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、一個Intent對應多種匹配結(jié)果的處理說明
一個intent有多個可匹配的處理組件,系統(tǒng)如何處理?
分響應消息的組件類型:
1)如果是service那么這些service都可以啟動并處理消息。
2)如果是Activity則會彈出一個對話框讓用戶進行選擇。

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

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

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的通信機制
有了Intent這種基于消息的進程內(nèi)或進程間通信模型,我們就可以通過Intent去開啟一個Service,可以通過Intent跳轉(zhuǎn)到另一個Activity,不論上面的Service或Activity是在當前進程還是其它進程內(nèi)即不論是當前應用還是其它應用的Service或Activity,通過消息機制都可以進行通信!

但是通過消息機制實現(xiàn)的進程間通信,有一個弊端就是,如果我們的Activity與Service之間的交往不是簡單的Activity開啟Service操作,而是要隨時發(fā)一些控制請求,那么必須就要保證Activity在Service的運行過程中隨時可以連接到Service。

eg:音樂播放程序
后臺的播放服務往往獨立運行,以方便在使用其他程序界面時也能聽到音樂。同時這個后臺播放服務也會定義一個控制接口,比如播放,暫停,快進等方法,任何時候播放程序的界面都可以連接到播放服務,然后通過這組控制接口方法對其控制。

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

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

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

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

IPC實現(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) ;
}

如果正確配置,會在gen下,生成同名的java文件
簡單摘要:
//我們需要實現(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
{
...
//獲取實例的方法asInterface
public static com.myq.android.MultiProcessTest.IDateTimeService asInterface(android.os.IBinder obj)
{
  ...
}
...
}
//我們自己的業(yè)務方法,需要實現(xiàn)的
public java.lang.String getCurrentDateTime(java.lang.String format) throws android.os.RemoteException;
}

2、Service中實現(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端代碼實現(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 ;
  }
} ;

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

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

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

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

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多