簡體   English   中英

具有默認內部類的Java接口

[英]Java Interface with Default Inner Class

我正在編寫一個具有兩個不同后台服務的android應用,一個用於發送和接收來自服務器的請求,另一個用於從url下載圖像。 應用程序的多個頁面需要執行這些活動,因此我編寫了兩個接口,用於處理服務器請求的RequestReceiver和用於下載圖像的ImageReceiver。

為了在Android中接收廣播的意圖,我正在擴展BroadcastReceiver類並覆蓋其onReceive()方法。 這應該通過意圖中的內部類來完成,該意圖在實現該類的類中調用一個方法。 但是,我不能從我的靜態內部類中調用非靜態方法。

public interface RequestReceiver {
    void handleRequest(int status, JSONObject object);

    class Receiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            int status = intent.getIntExtra("STATUS", -1);
            try {
                JSONObject object = new JSONObject(intent.getStringExtra("DATA"));
                handleRequest(status, object);
            } catch (JSONException e) {
                Log.e(this.toString(), "JSONException");
                e.printStackTrace();
            }
        }
    }
}

這不會編譯:

non-static method cannot be referenced from a static context

我應該怎么做?

編輯:我不能使用抽象類的原因是我需要多重繼承。 有些活動需要是ImageDownloader,而不是RequestReceivers,反之亦然。 同樣,實現此接口的類已經從其他類繼承。 有些擴展了Fragment,另一些擴展了Activity,但是它們都需要訪問這些功能。 因此,它必須是一個接口。

您可以將包含非靜態方法的外部類的對象傳遞到靜態內部類中。 這可以通過構造函數或setter方法完成。 傳入的對象應分配給靜態內部類的成員變量。

然后,您可以使用傳遞到靜態內部類構造函數或setter中的外部類的對象來調用非靜態方法。

您可以執行以下操作:

public interface RequestReceiver {
    void handleRequest(int status, JSONObject object);

    class MyBroadcastReceiver extends BroadcastReceiver {

        private final RequestReceiver requestReceiver;

        public MyBroadcastReceiver(RequestReceiver requestReceiver) {
            this.requestReceiver = requestReceiver;
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            int status = intent.getIntExtra("STATUS", -1);
            try {
                JSONObject object = new JSONObject(intent.getStringExtra("DATA"));
                requestReceiver.handleRequest(status, object);
            } catch (JSONException e) {
                Log.e(this.toString(), "JSONException");
                e.printStackTrace();
            }
        }
    }
}

我沒有嘗試代碼...所以可能會有一些錯誤...但是你明白了

在跳入StackOverflow之前,我應該喝咖啡。

無論如何…

您正在嘗試從靜態內部類訪問非靜態方法(這就是Java的工作方式)。

盡管提供了一些提供解決方法的方法,但這通常會突出顯示更高級別的體系結構問題。

為什么在接口中有一個類,為什么該類是BroadcastReceiver?

您不應該嘗試以不同的方式抽象一下嗎?

我個人會對這種代碼不滿意。 您試圖在代碼中解釋的目的是什么? 當我閱讀此代碼時,應該從中推斷出什么? 這種界面的意圖是什么?

我是否應該使用此接口並關心其中是否有廣播接收器?

我認為您應該重新考慮以其他方式編寫此代碼,而不是嘗試與工具/語言作斗爭。

我將如何處理您的問題?

應用程序的多個頁面需要執行這些活動

1)發送和接收來自服務器的請求

2)從url下載圖像

為什么不在抽象類中創建這些實現,每個活動在需要此類行為時可以擴展這些抽象類。 (如果您確實需要這些方法,可以稍后再對其進行接口)。

每個實現的細節都與孩子無關。 如果您的“圖像下載器”代碼發生更改,您也不想更改每個活動。

重新考慮你的問題:)

更新:

我感到您在“面向對象”世界中迷路了。 我強烈建議您看一下這本(舊但仍然有效)的書:Robert C. Martin撰寫的《 敏捷軟件開發,原理,模式和實踐》

不要被它的標題所迷惑,這不是一本有關“ Scrum會議”的書。

我不特別知道有關您的問題的實現細節,但是我建議您重新考慮您的設計。 圖像下載和網絡請求/響應本身與活動無關,並且不必由活動通過接口來實現。

您應該考慮采用一種更加“面向工廠”的方法(而且我討厭命名“模式”,因為我認為它們傾向於使事情“過於復雜”)。

盡管我不同意另一本書中的建議,但我還是推薦100%。 我從中學到了一些有趣的東西,我認為這是幾年后寫的《敏捷》的前傳;)

必須發出請求的Activity應調用您的DAO(數據訪問對象)並請求數據。 數據可能來自網絡,可能來自本地緩存,可能來自本地文件,誰知道。 該活動當然不在乎。 而且不應該。

從URL下載圖像可能留給了像Picasso這樣簡單而健壯的庫,但是如果您堅持要編寫自己的庫,則實現和用法決不應與特定的Activity綁定。

沒有更多信息,很難說出您所面臨的確切問題以及如何解決該問題。

您的特定問題(非靜態方法錯誤)清楚地表明您正在嘗試采用非標准/ hacky解決方案,並且應該采取一些措施,以免為時已晚(如我所鏈接的第二本書)會很高興地解釋);)

暫無
暫無

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

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