如何将数据从非活动类传递到android中的活动?

时间:2013-07-22 19:29:44

标签: java android android-intent

我正在构建我的应用程序,我正在使用socket.io与网络服务器进行通信。我有java文件来处理那些不是活动并在后台运行的文件。因此,要启动它们,它将在活动中实例化,并且套接字将运行。现在,Web服务器会触发我在回调中处理的消息,并将数据传递给活动。现在我正在寻找将数据从正在运行的非活动类传递到当前正在运行的活动的最佳方法。

我之前做过的是使用非活动类创建的意图,该意图将数据发送到当前正在运行的活动。必须将行为改为单个实例或单个实例,以避免活动继续重新启动。 问题是形成我的主要行为我不能使用单顶启动模式因为我需要在某些情况下自我刷新。

所以我无法正确处理主要活动的套接字,因为如果我将主要活动改为singletop,那么我只能收到数据,这对于应用来说并不理想。我首先尝试在非活动类调用的活动中命名一个函数,但似乎这是非法的,所以我非常困在这里。

@Override
    public void on(String event, IOAcknowledge ack, Object... data) {

        System.out.println("Server may have triggered event '" + event + "'");

        if (event.equals("message")) {
        System.out.println(data[2]);

        Intent newIntent = new Intent(Chat.mContent, Chat.class);
        Bundle extras=new Bundle();
        extras.putString("name", (String)data[1]);
        extras.putString("MSG", (String)data[2]);
        newIntent.putExtras(extras);


        Chat.mContent.startActivity(newIntent);

        }
        if (event.equals("ready")) {
            System.out.println("Received the ready callback");
            try{
            Intent newIntent = new Intent(TabExercise.mContext, TabExercise.class);
            newIntent.putExtra("ready", event);
            TabExercise.mContext.startActivity(newIntent);
            }catch(Exception e){
                System.out.println("Caught an error");
            }


        }
    }

这是非活动类中发送数据的方法。

@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Bundle extras=intent.getExtras();

if (intent.hasExtra("ready")) {
    // Retrieve the message and call getMsg(String)
   connect.starter(SaveSharedPreference.getName(TabExercise.this), SaveSharedPreference.getUserId(TabExercise.this));

}

}

这是主要活动中捕获意图的地方。不理想。

2 个答案:

答案 0 :(得分:2)

我认为您可能会发现有用的是使用Singletons或非UI Fragment。如果您还没有为您的UI使用Fragments,那么您绝对应该look into it,因为它是现代Android应用程序的法律标准。更重要的是,Android支持库将Fragments一直提供给Android 1.6,这是向后兼容的理想选择。

您可以在线程之间使用Handlers同样传递数据和消息。这些基本上提供了一个管道,您可以posthandleMessage发送消息。您可能会在Application onCreate中启动网络内容,并可能将该主题存储为singleton。然后,您可以将对您的用户界面Handler的引用传递给此主题,然后通过发布Runnables直接与您的用户界面进行通信。

一个有趣的答案是“更好”'可以在这里找到:

Non-UI Fragment vs Singleton

答案 1 :(得分:1)

据我了解这个问题,你开始你的活动,从那里开始你的CommunicationHandler实例?

然后你将让你的活动实现任何类型的CallBack接口,用CallBack实现你的Handler(意思是:活动)并调用CallBacks调用方法。

有关如何使用回调的详细信息,请参阅this question and it's answer

对不起,如果我理解错了: - )

修改

您的MainActivity(启动SocketConnector并接收消息的那个)应该提供回调接口的实现。界面看起来像这样:

public interface IMessageReceiver {
  public void onMessageReceived(Message m);
}

将您的Message类看起来像:

public class Message {
  String name;
  String msg;
  //add getter/setter and constructor to fit your needs
}

那么你的主要活动应该是:

public class MainActivity extends Activity implements IMessageReceiver {
  //... main activity code here.
    SocketConnector mySC = new SocketConnector(this);
  //... more main activity code here.
  public void onMessageReceived(Message m) {
    //do something with the message, e.g. display to edit texts, lists etc.
  }
}

在您的SocketConnector中,您将IMessageReceiver定义为最终成员并调用receiver.onMessageReceived(m) - 应该像

IMessageReceiver receiver

public SocketConnector(IMessageReceiver receiver) {
  this.receiver = receiver;
}

@Override
public void on(String event, IOAcknowledge ack, Object... data) {
  if (event.equals("message")) {
      System.out.println(data[2]);

      //Intent newIntent = new Intent(Chat.mContent, Chat.class);
      //Bundle extras=new Bundle();
      //extras.putString("name", (String)data[1]);
      //extras.putString("MSG", (String)data[2]);
      //newIntent.putExtras(extras);


      //Chat.mContent.startActivity(newIntent);
      Message m = new Message();
      m.name = (String)data[0];
      m.msg = (String)data[1];
      this.receiver.onMessageReceived(m);
    }
}