在 Android 中使用接口回调
Using interface callbacks in Android
我目前正在尝试在 Android 上编写一个简单的聊天应用程序。
它获取语音,将其转换为文本,然后将其发送到服务器。
我希望能够使用 TextToSpeech 来读取服务器给出的响应。
我不断收到 java.lang.NullPointerException: Attempt to invoke interface method 'void {MYAPPNAME}.MyCallback.callbackCall()' on a null object reference
。我看过其他有类似答案的问题,但它们相互矛盾,如他们所说 "the interface should be instantiated first" 或 "you don't instantiate interfaces" 等,让我感到困惑。
接收者:
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
您没有在任何地方设置 callback
。您将其定义为 MyCallback
并为其命名 callback
但它仍然没有分配任何内容,因此当您点击 callback.callbackCall();
时会出现 NullPointerException
我假设您想将它设置为您链接的 MainActivity
,因此您必须通过构造函数将其传递到 ClientThread
,例如:
public class ClientThread implements Runnable {
public ClientThread(MyCallback callback){
this.callback = callback;
}
}
然后更改:
cThread = new ClientThread();
到
cThread = new ClientThread(this);
但是如果你的回调函数想要做任何 UI 相关的事情,或者任何应该在主线程上 运行 的事情,你将不得不使用一个处理程序来 post 它到主线程。如果你想这样做,最简单的方法是将 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;
}
}
}
然后将回调位更改为:
Handler mainHandler = new Handler(mCtx.getMainLooper());
mainHandler.post(new Runnable() {
@Override
public void run() {
callback.callbackCall();
}
});
我目前正在尝试在 Android 上编写一个简单的聊天应用程序。
它获取语音,将其转换为文本,然后将其发送到服务器。
我希望能够使用 TextToSpeech 来读取服务器给出的响应。
我不断收到 java.lang.NullPointerException: Attempt to invoke interface method 'void {MYAPPNAME}.MyCallback.callbackCall()' on a null object reference
。我看过其他有类似答案的问题,但它们相互矛盾,如他们所说 "the interface should be instantiated first" 或 "you don't instantiate interfaces" 等,让我感到困惑。
接收者:
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
您没有在任何地方设置 callback
。您将其定义为 MyCallback
并为其命名 callback
但它仍然没有分配任何内容,因此当您点击 callback.callbackCall();
NullPointerException
我假设您想将它设置为您链接的 MainActivity
,因此您必须通过构造函数将其传递到 ClientThread
,例如:
public class ClientThread implements Runnable {
public ClientThread(MyCallback callback){
this.callback = callback;
}
}
然后更改:
cThread = new ClientThread();
到
cThread = new ClientThread(this);
但是如果你的回调函数想要做任何 UI 相关的事情,或者任何应该在主线程上 运行 的事情,你将不得不使用一个处理程序来 post 它到主线程。如果你想这样做,最简单的方法是将 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;
}
}
}
然后将回调位更改为:
Handler mainHandler = new Handler(mCtx.getMainLooper());
mainHandler.post(new Runnable() {
@Override
public void run() {
callback.callbackCall();
}
});