简体   繁体   English

具有默认内部类的Java接口

[英]Java Interface with Default Inner Class

I am writing an android app that has two different background services, one to send and receive requests from a server, and one to download images from url's. 我正在编写一个具有两个不同后台服务的android应用,一个用于发送和接收来自服务器的请求,另一个用于从url下载图像。 Multiple pages of the app need to do these activities, so I wrote two interfaces, RequestReceiver for handling server requests, and ImageReceiver for downloading images. 应用程序的多个页面需要执行这些活动,因此我编写了两个接口,用于处理服务器请求的RequestReceiver和用于下载图像的ImageReceiver。

To receive a broadcasted intent in Android, I am extending the BroadcastReceiver class and overriding its onReceive() method. 为了在Android中接收广播的意图,我正在扩展BroadcastReceiver类并覆盖其onReceive()方法。 This should be done via an inner class in the intent that calls a method in the class that implemented it. 这应该通过意图中的内部类来完成,该意图在实现该类的类中调用一个方法。 But, I can't call a non-static method from my static inner class. 但是,我不能从我的静态内部类中调用非静态方法。

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();
            }
        }
    }
}

This doesn't compile: 这不会编译:

non-static method cannot be referenced from a static context

What should I do differently? 我应该怎么做?

EDIT: The reason I can't use an abstract class is that I need multiple inheritance. 编辑:我不能使用抽象类的原因是我需要多重继承。 Some activities need to be ImageDownloaders and not RequestReceivers, and vice versa. 有些活动需要是ImageDownloader,而不是RequestReceivers,反之亦然。 Also, the classes that are implementing this interface are already inheriting from other classes. 同样,实现此接口的类已经从其他类继承。 Some are extending Fragment and others are extending Activity, but they both need access to these abilities. 有些扩展了Fragment,另一些扩展了Activity,但是它们都需要访问这些功能。 Thus, it must be an interface. 因此,它必须是一个接口。

You could pass an object of the outer class, which contains the non-static method, into your static inner class. 您可以将包含非静态方法的外部类的对象传递到静态内部类中。 This could be done via a constructor or a setter method. 这可以通过构造函数或setter方法完成。 The object that is passed in should be assigned to a member variable of the static inner class. 传入的对象应分配给静态内部类的成员变量。

You could then call the non-static method using the object of the outer class that was passed into the static inner class constructor or setter. 然后,您可以使用传递到静态内部类构造函数或setter中的外部类的对象来调用非静态方法。

You could do something like this: 您可以执行以下操作:

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();
            }
        }
    }
}

I didn't try the code... so there might be some errors... but you get the idea 我没有尝试代码...所以可能会有一些错误...但是你明白了

I should drink coffee before jumping into StackOverflow. 在跳入StackOverflow之前,我应该喝咖啡。

Anyway… 无论如何…

you're trying to access a non-static method from your static inner class (that's how Java works). 您正在尝试从静态内部类访问非静态方法(这就是Java的工作方式)。

Although some methods to provide a workaround have been provided, this usually highlights a higher level architecture problem. 尽管提供了一些提供解决方法的方法,但这通常会突出显示更高级别的体系结构问题。

Why are you having a class inside an interface and why is this class a BroadcastReceiver? 为什么在接口中有一个类,为什么该类是BroadcastReceiver?

Shouldn't you be trying to abstract this a little bit differently? 您不应该尝试以不同的方式抽象一下吗?

I would personally frown at such code. 我个人会对这种代码不满意。 What is the intent you're trying to explain in your code? 您试图在代码中解释的目的是什么? When I read this code, what am I supposed to infer from it? 当我阅读此代码时,应该从中推断出什么? What's the intention of such interface? 这种界面的意图是什么?

Am I supposed to use this interface and care that there's a broadcast receiver in it? 我是否应该使用此接口并关心其中是否有广播接收器?

I think you should reconsider writing this code differently, rather than try to fight the tools/language. 我认为您应该重新考虑以其他方式编写此代码,而不是尝试与工具/语言作斗争。

How would I approach your problem? 我将如何处理您的问题?

Multiple pages of the app need to do these activities 应用程序的多个页面需要执行这些活动

1) Send and receive requests from a server 1)发送和接收来自服务器的请求

2) Download images from url's 2)从url下载图像

Why not create these implementations in an abstract classes that each activity can extend when they need such behavior. 为什么不在抽象类中创建这些实现,每个活动在需要此类行为时可以扩展这些抽象类。 (You can interface the methods later if you really need them). (如果您确实需要这些方法,可以稍后再对其进行接口)。

The details of each implementation doesn't really concern the children. 每个实现的细节都与孩子无关。 Nor you want to change each activity should your "image downloader" code changes. 如果您的“图像下载器”代码发生更改,您也不想更改每个活动。

Re-think your problem :) 重新考虑你的问题:)

UPDATE: 更新:

I have the feeling you're lost in the "Object Oriented" world. 我感到您在“面向对象”世界中迷路了。 I strongly recommend you take a look at this (old but still valid) book: Agile Software Development, Principles, Patterns, and Practices by Robert C. Martin. 我强烈建议您看一下这本(旧但仍然有效)的书:Robert C. Martin撰写的《 敏捷软件开发,原理,模式和实践》

Don't be fooled by its title tho, this is not a book about "Scrum meetings". 不要被它的标题所迷惑,这不是一本有关“ Scrum会议”的书。

I don't know the implementation details about your problem in particular, but I suggest you re-think your design; 我不特别知道有关您的问题的实现细节,但是我建议您重新考虑您的设计。 image downloading and network request/response have nothing to do with activities per-se and should not have to be implemented by an activity through an interface. 图像下载和网络请求/响应本身与活动无关,并且不必由活动通过接口来实现。

You should consider having a more "Factory-Oriented" approach (And I hate naming "patterns" because I think they tend to "over-complicate" things). 您应该考虑采用一种更加“面向工厂”的方法(而且我讨厌命名“模式”,因为我认为它们倾向于使事情“过于复杂”)。

Although I don't agree 100% with the suggestions made in this other book , I also recommend it. 尽管我不同意另一本书中的建议,但我还是推荐100%。 I've learned a few interesting things out of it and I think it's a prequel of the Agile one, written years later ;) 我从中学到了一些有趣的东西,我认为这是几年后写的《敏捷》的前传;)

An Activity that has to make a request, should call your DAO (Data Access Object) and request for the data. 必须发出请求的Activity应调用您的DAO(数据访问对象)并请求数据。 The data may come from the network, may come from a local cache, may come from a local file, who knows. 数据可能来自网络,可能来自本地缓存,可能来自本地文件,谁知道。 The activity certainly doesn't care. 该活动当然不在乎。 And it shouldn't. 而且不应该。

Downloading an image from a URL is probably left to a simple and robust library like Picasso , but if you insist on writing your own, then, the implementation and usage should never be tied to a particular Activity . 从URL下载图像可能留给了像Picasso这样简单而健壮的库,但是如果您坚持要编写自己的库,则实现和用法决不应与特定的Activity绑定。

Without any more information, it's hard to tell what exact problem you're facing and how you are trying to solve it. 没有更多信息,很难说出您所面临的确切问题以及如何解决该问题。

Your particular problem (the non-static method error) is a clear indicator that you're trying to go towards a non-standard/hacky solution and you should take a couple of steps back before it's too late (as the second book I linked will happily explain) ;) 您的特定问题(非静态方法错误)清楚地表明您正在尝试采用非标准/ hacky解决方案,并且应该采取一些措施,以免为时已晚(如我所链接的第二本书)会很高兴地解释);)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM