我使用json解析来连接我的php chatbot与android。当我有一个用于文本输入的editText时,代码可以正常工作。但当我实现语音到文本输入的语音识别时,我的应用程序突然停止。我收到以下错误。
04-18 00:25:11.928: E/AndroidRuntime(21316): FATAL EXCEPTION: AsyncTask #1
04-18 00:25:11.928: E/AndroidRuntime(21316): Process: com.chatbot.mavis, PID: 21316
04-18 00:25:11.928: E/AndroidRuntime(21316): java.lang.RuntimeException: An error occured while executing doInBackground()
04-18 00:25:11.928: E/AndroidRuntime(21316): at android.os.AsyncTask$3.done(AsyncTask.java:300)
04-18 00:25:11.928: E/AndroidRuntime(21316): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
04-18 00:25:11.928: E/AndroidRuntime(21316): at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
04-18 00:25:11.928: E/AndroidRuntime(21316): at java.util.concurrent.FutureTask.run(FutureTask.java:242)
04-18 00:25:11.928: E/AndroidRuntime(21316): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
04-18 00:25:11.928: E/AndroidRuntime(21316): at java.util.concurrent.ThreadPoolExecutor.runWorker
(ThreadPoolExecutor.java:1112)
04-18 00:25:11.928: E/AndroidRuntime(21316):at java.util.concurrent.ThreadPoolExecutor$Worker.run
(ThreadPoolExecutor.java:587)
04-18 00:25:11.928: E/AndroidRuntime(21316):at java.lang.Thread.run(Thread.java:841)
04-18 00:25:11.928: E/AndroidRuntime(21316):Caused by: java.lang.NullPointerException
04-18 00:25:11.928: E/AndroidRuntime(21316):at libcore.net.UriCodec.encode(UriCodec.java:132)
04-18 00:25:11.928: E/AndroidRuntime(21316):at java.net.URLEncoder.encode(URLEncoder.java:57)
04-18 00:25:11.928: E/AndroidRuntime(21316):at com.chatbot.mavis.Speech$GetBotResponse.doInBackground(Speech.java:182)
04-18 00:25:11.928: E/AndroidRuntime(21316):at com.chatbot.mavis.Speech$GetBotResponse.doInBackground(Speech.java:1)
04-18 00:25:11.928: E/AndroidRuntime(21316):at android.os.AsyncTask$2.call(AsyncTask.java:288)
04-18 00:25:11.928: E/AndroidRuntime(21316):at java.util.concurrent.FutureTask.run(FutureTask.java:237)
04-18 00:25:11.928: E/AndroidRuntime(21316):... 4 more
这是我的代码:
package com.chatbot.mavis;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import org.json.JSONException;
import org.json.JSONObject;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.ActionBar.LayoutParams;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@SuppressLint("InlinedApi")
public class Speech extends Activity {
protected static final int Result_speech = 1;
String usertext;
String ask;
String str_botsay, str_convo_id;
String str_usersay;
TextView tvbt, tvut;
LinearLayout finlins;
LinearLayout ll1, ll2;
ImageView ui, bi;
String TAG_USERSAY = "usersay";
String TAG_BOTSAY = "botsay";
String TAG_CONVO_ID = "convo_id";
JSONParser jParser = new JSONParser();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_speech);
finlins = (LinearLayout) findViewById(R.id.lins);
final ScrollView scvs = (ScrollView) findViewById(R.id.svs);
final Button btns = (Button) findViewById(R.id.button1s);
btns.setOnClickListener(new View.OnClickListener() {
@SuppressLint("NewApi")
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
ui = new ImageView(v.getContext());
bi = new ImageView(v.getContext());
tvut = new TextView(v.getContext());
tvbt = new TextView(v.getContext());
Intent intent = new Intent(
RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "en-US");
try {
startActivityForResult(intent, Result_speech);
tvut.setText("");
} catch (ActivityNotFoundException e) {
Toast t = Toast.makeText(getApplicationContext(),
"Your device does not support speech to text",
Toast.LENGTH_SHORT);
t.show();
}
}
});
scvs.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
scvs.post(new Runnable() {
public void run() {
scvs.fullScroll(View.FOCUS_DOWN);
}
});
}
});
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@SuppressLint("InlinedApi")
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case Result_speech: {
if (resultCode == RESULT_OK && null != data) {
ArrayList<String> text = data
.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
ll1 = new LinearLayout(Speech.this);
ll2 = new LinearLayout(Speech.this);
final LayoutParams lparams = new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
final LayoutParams lparams2 = new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
ll1.setLayoutParams(lparams);
ll1.setOrientation(LinearLayout.HORIZONTAL);
ll2.setLayoutParams(lparams);
ll2.setOrientation(LinearLayout.HORIZONTAL);
finlins.addView(ll1);
finlins.addView(ll2);
ui.setLayoutParams(lparams2);
bi.setLayoutParams(lparams2);
tvut.setLayoutParams(lparams);
tvbt.setLayoutParams(lparams);
ll1.addView(ui);
ll1.addView(tvut);
ll2.addView(bi);
ll2.addView(tvbt);
tvut.setTextColor(Color.BLACK);
tvut.setBackgroundResource(R.drawable.user_bubble);
tvbt.setTextColor(Color.BLACK);
tvbt.setBackgroundResource(R.drawable.bot_bubble);
ll1.setPadding(0, 0, 0, 5);
ll2.setPadding(0, 0, 0, 35);
//new GetBotResponse().execute();
ui.setImageResource(R.drawable.user);
ui.setPadding(0, 0, 25, 0);
bi.setImageResource(R.drawable.bot);
bi.setPadding(0, 0, 25, 0);
usertext = text.get(0);
tvut.setText(usertext);
}
new GetBotResponse().execute();
break;
}
}
}
private class GetBotResponse extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
try {
ask = URLEncoder.encode(usertext, "UTF-8");
Log.d("TEST", ask);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String url = "http://192.168.1.3/programo/chatbot/conversation_start.php?format=json&say="
+ ask;
String URL = url.toString();
JSONObject json = jParser.getJSONFromUrlByGet(URL);
try {
String str_usersay = json.getString(TAG_USERSAY);
Log.i("TAG_usersay", str_usersay);
str_botsay = json.getString(TAG_BOTSAY);
Log.i("TAG_botsay", str_botsay);
str_convo_id = json.getString(TAG_CONVO_ID);
Log.i("TAG_convo_id", str_convo_id);
} catch (JSONException e) {
}
return null;
}
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
tvbt.setText(str_botsay);
}
}
}
答案 0 :(得分:1)
当您在usertext
中致电null
时,URLEncoder.encode
似乎doInBackground
。
在onActivityResult
中,您首先开始您的任务,然后为usertext
设置一个值。这不会起作用,因为任务可能已经开始在AsyncTask
的单独线程上运行。您可能希望在new GetBotResponse().execute();
之后移动tvut.setText(usertext);
行。
无论哪种方式,如果你不那么依赖共享变量,那可能会更好。在当前状态下,这非常容易出现并发问题,例如当用户连续多次快速点击时。这将导致多个任务同时运行,尝试读取和写入相同的变量,并可能产生不一致的结果。
GetBotResponse
仅需要usertext
作为输入,并生成str_usersay
,str_botsay
和str_convo_id
作为输出。您可以usertext
final
GetBotResponse
字段onPostExecute
并在其构造函数中传递值。您还可以为这三个字符串创建一个包装类,并让任务返回一个实例,然后在onPostExecute
中使用该实例。
通过这种方式,您可以摆脱这些共享变量,而不必在以后讨厌令人讨厌的并发问题。你仍然可以在tvbt
中使用一些共享变量来处理用户界面(例如访问{{1}}),但你不会遇到麻烦:那时你又回到了GUI线程上。 ; - )
答案 1 :(得分:0)
似乎usertext
为空,您只是在onActivityResult
初始化