我目前正在根据下面发布的代码实现自定义事件和监听器。我被告知这是一个非常脏的实现,这需要改变。但是,我是java和android的新手,并没有看到当前实现有什么问题。 我在下面的方式工作,似乎也在做我需要的一切。我想知道是否有些人可以请一看我的代码并就我应该改变什么以及我做错了提出一些建议。以我的例子并修改它以便我可以看到你所说的将是什么非常感谢。
提前致谢!
/* SmartApp.java */
public class SmartApp extends Activity
{
private ConnectDevice cD = new ConnectDevice();
private DataRobot dR = new DataRobot();
private DataBuilder dB = new DataBuilder();
private DataSender dS = new DataSender();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.intro);
cD.addDataReceivedListener(new DataReceivedListener() {
@Override
public void dataReceivedReceived(DataReceivedEvent event) {
// TODO Auto-generated method stub
dR.analyzeData(event.getData());
}
});
dR.addDataAnalyzedListener(new DataAnalyzedListener() {
@Override
public void dataAnalyzedReceived(DataAnalyzedEvent event) {
// TODO Auto-generated method stub
dB.submitData(event.getData());
}
});
dB.addDataBuilderListener(new DataBuilderListener() {
@Override
public void dataBuilderReceived(DataBuilderEvent event) {
// TODO Auto-generated method stub
dS.sendData(event.getData());
}
});
}
}
/* ConnectDevice.java
* This class is implementing runnable because i have a thread running that is checking
* the contents of a socket. Irrelevant to events. */
public class ConnectDevice implements Runnable {
private List _listeners = new ArrayList();
private String data;
/* Constructor */
public ConnectDevice() {// does some socket stuff here, irrelevant to the events}
public void run() {// does some socket stuff here, irrelevant to the events}
public synchronized void addDataReceivedListener(DataReceivedListener listener) {
_listeners.add(listener);
}
public synchronized void removeDataReceivedListener(DataReceivedListener listener) {
_listeners.remove(listener);
}
private synchronized void fireDataReceivedEvent(String temp) {
DataReceivedEvent dRE = new DataReceivedEvent(this, temp);
Iterator listeners = _listeners.iterator();
while(listeners.hasNext()) {
((DataReceivedListener)listeners.next()).dataReceivedReceived(dRE);
}
}
public interface DataReceivedListener {
public void dataReceivedReceived(DataReceivedEvent event);
}
}
/* DataRobot.java */
public class DataRobot {
/* This class is for analyzing the data */
private List _listeners = new ArrayList();
private String data;
public boolean analyzeData(String temp) {
/* Analyze the data
* This function analyzes the data, as explained in the OP
* This function fires the analyzed data event when finished
* analyzing the data.
*/
data = temp;
fireDataAnalyzedEvent(data); // this fires the dataanalyzedevent
return true; //for now this will always return true
}
public synchronized void addDataAnalyzedListener(DataAnalyzedListener listener) {
_listeners.add(listener);
}
public synchronized void removeDataAnalyzedListener(DataAnalyzedListener listener) {
_listeners.remove(listener);
}
private synchronized void fireDataAnalyzedEvent(String temp) {
DataAnalyzedEvent dRE = new DataAnalyzedEvent(this, temp);
Iterator listeners = _listeners.iterator();
while(listeners.hasNext()) {
((DataAnalyzedListener)listeners.next()).dataAnalyzedReceived(dRE);
}
}
public interface DataAnalyzedListener {
public void dataAnalyzedReceived(DataAnalyzedEvent event);
}
}
/* DataBuilder.java */
public class DataBuilder {
private List _listeners = new ArrayList();
private String data;
public boolean submitData(String temp) {
/* Builds the data
* This function builds the data, as explained in the OP
* This function fires the databuilder data event when finished
* building the data.
*/
data = temp;
fireDataBuilderEvent(data); //firing the databuilder event when finished
return true;
}
public synchronized void addDataBuilderListener(DataBuilderListener listener) {
_listeners.add(listener);
}
public synchronized void removeDataBuilderListener(DataBuilderListener listener) {
_listeners.remove(listener);
}
private synchronized void fireDataBuilderEvent(String temp) {
DataBuilderEvent dRE = new DataBuilderEvent(this, temp);
Iterator listeners = _listeners.iterator();
while(listeners.hasNext()) {
((DataBuilderListener)listeners.next()).dataBuilderReceived(dRE);
}
}
public interface DataBuilderListener {
public void dataBuilderReceived(DataBuilderEvent event);
}
}
/* DataSender.java */
/* this class has no event, because it is done firing events at this point */
public class DataSender {
private String data;
public boolean sendData(String temp) {
data = temp;
return true;
}
}
下面是每个事件的事件对象。我将每个都定义在一个单独的文件中,不确定这是否是好的程序。
/* DataReceivedEvent.java */
public class DataReceivedEvent extends EventObject{
private String data;
public DataReceivedEvent(Object source, String temp) {
super(source);
// TODO Auto-generated constructor stub
data = temp;
}
public String getData() {
// this function is just an accessor function
return data;
}
}
/* DataAnalyzedEvent.java */
public class DataAnalyzedEvent extends EventObject{
private String data;
public DataAnalyzedEvent(Object source, String temp) {
super(source);
// TODO Auto-generated constructor stub
data = temp;
}
public String getData() {
// this function is just an accessor function
return data;
}
}
/* DataBuilderEvent.java */
public class DataBuilderEvent extends EventObject {
private String data;
public DataBuilderEvent(Object source, String temp) {
super(source);
// TODO Auto-generated constructor stub
data = temp;
}
public String getData() {
// this function is just an accessor function
return data;
}
}
答案 0 :(得分:2)
我不会说这是一个“非常糟糕的实现”。在我看来,使用回调/观察者/听众是一种很好的做法。
当我编写Android应用程序时,我喜欢将其分层,使得“应用程序”是普通的旧Java,没有Android导入,理论上可以在Swing应用程序,基于Java EE的网站等中使用。“Android “部分是严格的用户界面。
我使用的回调是允许Android代码注册对应用程序中发生的事件的兴趣。例如,在二十一点游戏中,Activity
可能会调用game.getDealer().playHand()
来告诉应用程序执行经销商手牌游戏逻辑。当该逻辑在应用程序中执行时,会触发事件,如cardDrawn(card)
,cardFlipped(card)
,handTotalChanged(handTotal)
等。应用程序的Android部分会监听这些事件并相应地重新绘制屏幕上的内容(但是它对二十一点一无所知。
我实际上只是让我的活动实现了CardListener
,HandListener
等界面,所以他们可以直接接收事件(不像你这样做),但你的风格不一定是坏事方式。
答案 1 :(得分:2)
我在理论上同意@SingleShot,因为你的Android应用程序的部分可以与Android无关,只要所有间接层引入的开销不会使应用程序放慢太多。恕我直言,在许多应用程序中,相对较少适合此描述。
在另一篇文章中,您提出了上述解决方案,以便将一项活动与另一项活动进行通信。在Android中,活动不仅仅是一些你可以随意抛出的Java对象。它们由操作系统管理,具有特定的生命周期。虽然观察者/可观察模式在某些地方非常令人愉快,但是观察者/可观察连接会产生垃圾收集问题的地方是不合适的。特别是,一个活动不能也不应该试图在另一个活动上持有某种监听器接口。
同样,一个干净的观察者/可观察模式可能会面对数据库,线程,服务和Android现实的其他部分而崩溃。
因此,在与Android隔离的纯Java代码中,您所拥有的可能是正常的。但是,除非您知道它将适用于那些特定于Android的问题,否则不要将其推荐为Android特定问题的解决方案。而且,当您开始尝试使您的代码在Android应用程序中运行时,如果您在尝试使您的教科书模式实施在Android应用程序的限制范围内工作时遇到问题,请不要感到震惊。