在Android中使用界面回调

时间:2015-08-08 00:15:47

标签: java android tcp callback

我目前正在尝试在Android上编写一个简单的聊天应用程序。

它需要语音,将其转换为文本,然后将其发送到服务器。

我希望能够使用TextToSpeech来读取服务器给出的响应。

我一直在java.lang.NullPointerException: Attempt to invoke interface method 'void {MYAPPNAME}.MyCallback.callbackCall()' on a null object reference。我已经查看了其他类似答案的问题,但它们是冲突的,因为他们说"接口应该首先实例化"或者"你没有实例化界面"等等,让我感到困惑。

接收者:

public class MainActivity extends ActionBarActivity implements TextToSpeech.OnInitListener, MyCallback {
    ...

    private void sendToServer(String msg) {
        cThread = new ClientThread();
        cThread.msg = msg;
        Thread thread = new Thread(cThread);
        thread.start();
    }

    @Override
    public void callbackCall() {
        Log.d("CALLBACK", cThread.serverResponseSaved);
        // Do the speaking here.
    }
}

负责消息的实际代码:

interface MyCallback {
    public void callbackCall();
}

public class ClientThread implements Runnable {
    String address = "XXX.XXX.X.XX";
    int port = YYYYY;
    boolean connected = false;
    String msg = "";
    private String serverResponse;
    String serverResponseSaved;
    MyCallback callback;

    @Override
    public void run() {
        try {
            Socket socket = new Socket(address, port);
            this.connected = true;
            while(connected) {
                try {
                    PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
                    out.println(this.msg);
                    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                        if ((serverResponse = in.readLine()) != null) {
                            serverResponseSaved = serverResponse;
                            Log.i("server says", serverResponseSaved);
                            callback.callbackCall();
                        }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            this.connected = false;
        }
    }
}

我实现界面的方式是错误的吗?

编辑:

尝试通过以下方式实例化它: callback = new MyCallback(); 给我一个'MyCallback is abstract. Cannot be instantiated.'错误。

界面的使用基于: Here

1 个答案:

答案 0 :(得分:1)

您没有在任何地方设置dump(System.Text.Encoding.UTF8.GetBytes(str1)) ; dump(System.Text.Encoding.UTF8.GetBytes(str2)) ; dump(System.Text.ASCIIEncoding.Default.GetBytes(str1)) ; dump(System.Text.ASCIIEncoding.Default.GetBytes(str2)) ; private void dump(byte[] bytes) { // HexaDecimal display console.writeln(BitConverter.ToString(bytes)) ; } 。您将其定义为callback并为其命名MyCallback,但仍然没有为其指定任何内容,因此当您点击callback

NullPointerException

我假设您要将其设置为您链接的callback.callbackCall();,因此您必须通过以下构造函数将其传递到MainActivity

ClientThread

然后改变:

public class ClientThread implements Runnable {
     public ClientThread(MyCallback callback){
         this.callback = callback;
     }
}

cThread = new ClientThread();

但是如果你的回调函数想要做任何UI相关的事情,或者应该在主线程上运行的任何东西,你将不得不使用一个处理程序将它发布到主线程。如果你想这样做,最简单的方法是将cThread = new ClientThread(this); 传递给Context并执行以下操作:

ClientThread

然后将回调位更改为:

public class ClientThread implements Runnable {
     /*your things*/
     Context mCtx;
     public ClientThread(Context context){
         this.mCtx = context;
         if(context instanceof MainActivity){
             this.callback = (MainActivity) callback;
         }
     }
}