2014-11-25 65 views
1

我有一個活動,其中包含mqttQndroidClient類型的對象。這個對象我想將它傳遞給另一個活動。爲了實現這一點,我閱讀有關如何解決這樣的問題,我發現soltion是建立如下所示實現serializable類的,我做了以下內容:如何創建Serializable對象並傳遞給bundle.putSerializable(key,value)

client = new mqttAndroidClient(..,...,..,..,); 
Intent i = new Intent(act_1.this, act_2.class) 
clientObject = clientObj = new (CLIENT_OBJ_KEY, client); 
Bundle b = new Bundle(); 
b.putSerializable(CLIENT_OBJ_KEY, clientOb.getObjValue()); 

但是Eclipse強調b.putSerializable(CLIENT_OBJ_KEY, clientObjValue());紅色,它似乎我沒有正確地創造出一個serializable對象。

和實現serializable,如下看起來clientObject類:

public class ClientObject implements Serializable { 

    private String objectKey; 
    private MqttAndroidClient objectValue; 

    public ClientObject(String objectKey, MqttAndroidClient objectValue) { 

     this.objectKey = objectKey; 
     this.objectValue = objectValue; 
    } 

    public void setObjKey(String objectKey) { 

     this.objectKey = objectKey; 
    } 

    public String getObjKey() { 

     return this.objectKey; 
    } 

    public void setObjValue(MqttAndroidClient objValue) { 

     this.objectValue = objValue; 
    } 

    public MqttAndroidClient getObjValue() { 

     return this.objectValue; 
    } 
} 
+2

這是因爲mqqtAndroidClient本身是不可序列。 clientObjectValue()返回一個mqqtAndroidClient類型的對象,這不是可序列化的。 – stealthjong 2014-11-25 08:56:13

+0

實際上你有一個可序列化的對象。只需將實現可序列化的類的對象傳遞給捆綁值即可。 – LetsamrIt 2014-11-25 09:05:16

+0

@LetsAmrIt由於該類具有不可序列化的成員,細紅線將在運行時變成異常。 – EJP 2014-11-25 09:31:43

回答

0

請問方法clientObjValue()返回一個對象ClientObject? 類MqttAndroidClient是否也可序列化?

+0

請參閱編輯 – user2121 2014-11-25 09:02:58

+0

它是「b.putSerializable(CLIENT_OBJ_KEY,clientOb.getObjValue());」 – user2121 2014-11-25 09:03:22

6

我在您的解決方案中看到很多問題。最大的一個是:你不能在一個可序列化的對象中封裝一個不可序列化的對象,並希望這個對象能夠工作。要序列化每個字段必須是可序列化的,請閱讀手冊。

你在這裏解決什麼問題?

  1. 爲每項活動(時間/內存)創建一個客戶端是否昂貴?
  2. 你不想每次重新配置客戶端嗎?
  3. 你想在你的應用程序中使用單個實例嗎?

我對第一種情況的觀點是,不昂貴創建一個客戶端,當你需要一個(每個活動我想一個),通過讀取documentation約MqttAndroidClient據我瞭解,客戶端使用長時間運行service。該服務負責客戶端/服務器通信,因此,我假設客戶端是一個非常小的包裝器,可以簡化服務/活動通信。這意味着您可以創建儘可能多的客戶端。

這將我們引向第二點:您不想每次重新配置客戶端。 解決方案是創建一個工廠。基本上是這樣的:

public final class MqttClientFactory { 
    public static MqttAndroidClient createClientInstance(Context context, ...) { 
    MqttAndroidClient client = new MqttAndroidClient(context, ....); 
    // Configure your client here 
    return client; 
    } 
} 

現在你可以創建一個配置實例您Activity.onCreate(...)

@Override 
protected void onCreate (Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    ... 
    mMqttClient = MqttClientFactory.createClientInstance(this, ...); 
    ... 
} 

如果你想你的整個應用程序客戶端的一個實例,有很多的解決方案,這通常涉及使用一個singleton。我個人更喜歡避免單身人士,所以我建議用你自己的方法來覆蓋Application類,在那裏創建你的客戶實例並從你的活動中獲得對它的引用。

public class MyApplication extends Application { 
    private MqttAndroidClient mClient; 

    public void onCreate() { 
    super.onCreate(); 

    mClient = new MqttAndroidClient(this, ...); 

    ... 
    } 

    public final MqttAndroidClient getClient() { 
    return mClient; 
    } 
} 

您現在可以使用Context.getApplicationContext()Acticity.getAppliaction()到你的自定義應用程序的參考。 I.E.:

MqttAndroidClient sharedClient = ((MyApplication) getApplication()).getClient(); 

您需要將您的自定義應用程序添加到清單,請參閱文檔here

+0

謝謝你的回答。實際上我不想在應用程序中保留一個對象。用戶可以根據自己的需要創建多個客戶端。閱讀完代碼後,我仍然幾乎遇到同樣的問題,如何將客戶端對象從一個活動傳遞到另一個活動?「對不起,缺乏理解」 – user2121 2014-11-25 12:25:31

+0

嗨,我的觀點是你首先想到的是你是否真的需要在這些活動之間傳遞相同的實例。如果是這樣,請使用單例或通過您的自定義應用程序共享引用。以此作爲建議:在活動之間共享複雜對象的衝動是一個糟糕設計的症狀。 – j0n0 2014-11-25 13:42:30

+0

非常感謝這樣的建議。但情況是,我有一個活動,有一個按鈕「連接」,當按下一個客戶端應該連接到代理與一些選項(clientID,服務器URI,等等)2 - 另一個活動開始承載兩個片段(發佈和訂閱),並且在每個(pub和sub)片段中,具有相同ID和選項的相同客戶端應該用於發佈和訂閱。如果我使用bundle將連接選項傳遞給兩個片段,這意味着我需要創建一個新的客戶端,我不想這樣做。請指導和建議 – user2121 2014-11-25 14:03:59

相關問題