[英]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
}
同樣的事情,但是:
然后,如果我們使用MyCustomActivity擴展CustomActivity,我們可以創建一個MyCustomActivity意圖,如下所示:
Intent i = new MyCustomActivity().newIntent(getActivity(), 1);
它將起作用。
我為什么不建議這樣做:
讓我繼續講一下。 繼承有點像注塑成型的塑料:我們看到這種技術用來制造我們每天依賴的工具,但是如果我們在家做,那很可能會一團糟。
那是因為繼承比看起來要難。 如果三個活動都需要使用一種特定類型的參數,那是否意味着它們都應該成為活動的同一種? 可能不是。 我沒有足夠的空間或時間來學習它(其他人說得比以往任何時候都更好),但是足以說有很多這樣共享代碼的陷阱。
這是否意味着他們可以通過其他方式共享某些代碼? 當然! 將實現放在另一個類中,並使用自己的靜態newIntent()方法進行調用。 還有更多代碼,但是沒有這個陷阱。 因此,我建議改為這樣做。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.