簡體   English   中英

在API中使用靜態工廠方法

[英]Use static factory method in API

我正在編寫一個基本上是單個自定義活動的小型庫:

package com.example.android.somelibrary;

public class CustomActivity extends Activity {

    private static final String EXTRA_SOME_THING = "CustomActivity.EXTRA_SOMETHING";

    public static Intent newIntent(Context context, int arg1) {
        Intent intent = new Intent(context, CustomActivity.class);
        intent.putExtra(EXTRA_SOME_THING arg1);
        return intent;
    }

    //... other methods
}

我希望該庫的用戶能夠擴展此活動:

package com.example.android.myproject;

public class MyCustomActivity extends CustomActivity {
    //... some methods
}

但我希望用戶能夠依賴我的公共工廠newInstance()

// start MyCustomActivity
int someInt = 0;
Intent intent = MyCustomActivity.newIntent(getApplicationContext(), someInt);
startActivity(intent);

但是,當我嘗試以這種方式啟動活動時,出現錯誤:

android.content.ActivityNotFoundException: Unable to find explicit activity class {com.example.android.myproject/com.example.android.somelibrary.CustomActivity}; have you declared this activity in your AndroidManifest.xml?

我在各自的清單中聲明了這兩個活動:SomeLibrary清單中的CustomActivity和MyProject清單中的MyCustomActivity。

我很困惑,因為如果我更改啟動活動調用,一切都會正常進行:

Intent intent = new Intent(context, MyCustomActivity.class);
startActivity(intent);

這使我認為我已經在MyProject正確設置了所有模塊依賴項。 這僅僅是Java的限制嗎? 我不能以這種方式調用靜態方法(在子級上調用父方法)嗎?

這行不通。

CustomActivity.newIntent()是在CustomActivity類上定義的靜態方法。 該靜態方法返回一個指向CustomActivity.class的Intent。

因此,當您調用MyCustomActivity.newIntent()時,會得到什么? 指向CustomActivity.class的意圖。 因為這就是CustomActivity中定義的方法。 觸發該意圖將不起作用,因為在應用的清單中未定義CustomActivity。 無論如何,這並不重要,因為您要啟動MyCustomActivity,而不是CustomActivity。

您想要的是一個靜態方法,它“知道”將調用哪個類名。 不幸的是,這在Java中是不可能的。

現在,這么說...我將向您展示如何做到這一點。 不過,我不建議這樣做。 (稍后再說為什么)

無論如何,就像我說的那樣:靜態方法不知道在哪個類上調用它們。 實例方法可以。 因此,您可以這樣做:

public class CustomActivity extends Activity {

    private static final String EXTRA_SOME_THING = "CustomActivity.EXTRA_SOMETHING";

    public Intent newIntent(Context context, int arg1) {
        Intent intent = new Intent(context, getClass());
        intent.putExtra(EXTRA_SOME_THING arg1);
        return intent;
    }

    //... other methods
}

同樣的事情,但是:

  • 這是一個實例方法,而不是靜態方法
  • 我們說的是getClass()(它動態返回當前實例的類),而不是說CustomActivity.class(它總是指向CustomActivity類)。

然后,如果我們使用MyCustomActivity擴展CustomActivity,我們可以創建一個MyCustomActivity意圖,如下所示:

Intent i = new MyCustomActivity().newIntent(getActivity(), 1);

它將起作用。

我為什么不建議這樣做:

  • 丑陋又怪異。 如果您想做某事並且語言使它變得丑陋和粗糙,則請使用hansolov(“讓語言取勝”);
  • 它啟用的技術不是一個好主意。

讓我繼續講一下。 繼承有點像注塑成型的塑料:我們看到這種技術用來制造我們每天依賴的工具,但是如果我們在家做,那很可能會一團糟。

那是因為繼承比看起來要難。 如果三個活動都需要使用一種特定類型的參數,那是否意味着它們都應該成為活動的同一種? 可能不是。 我沒有足夠的空間或時間來學習它(其他人說得比以往任何時候都更好),但是足以說有很多這樣共享代碼的陷阱。

這是否意味着他們可以通過其他方式共享某些代碼? 當然! 將實現放在另一個類中,並使用自己的靜態newIntent()方法進行調用。 還有更多代碼,但是沒有這個陷阱。 因此,我建議改為這樣做。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM