乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

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

       techres 2012-02-16

      android 應(yīng)用程序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 ,如果要針對第三方應(yīng)用需要Content Provider 

      4.基于IPC的通信機制

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

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

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


          在當(dāng)前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,相當(dāng)于Web程序的Application,它的生命周期和應(yīng)用程序一樣長(這個我喜歡)。

          那么現(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是屬于當(dāng)前應(yīng)用還是其它應(yīng)用的!
                                                                       
      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ù)是單個記錄
      如上設(shè)置,要重寫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對應(yīng)多種匹配結(jié)果的處理說明
      一個intent有多個可匹配的處理組件,系統(tǒng)如何處理?
      分響應(yīng)消息的組件類型:
      1)如果是service那么這些service都可以啟動并處理消息。
      2)如果是Activity則會彈出一個對話框讓用戶進行選擇。

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

      簡單一點說就是:權(quán)限設(shè)置問題
      我們可以自己定義permission,然后在需要的組件處設(shè)置該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是在當(dāng)前進程還是其它進程內(nèi)即不論是當(dāng)前應(yīng)用還是其它應(yīng)用的Service或Activity,通過消息機制都可以進行通信!

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

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

      如上的需求僅僅通過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服務(wù)需要超過幾毫秒的時間才能完成的話,你應(yīng)該避免在Activity的主線程中調(diào)用,否則IPC調(diào)用會掛起應(yīng)用程序?qū)е陆缑媸ロ憫?yīng)。在 這種情況下,應(yīng)該考慮單起一個線程來處理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è)務(wù)方法,需要實現(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運行在服務(wù)端進程。
      當(dāng)你通過aidl去訪問服務(wù)端時,客戶端會阻塞在proxy,服務(wù)端處理完后,通知proxy返回。

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

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

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

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多