致命异常AsyncTask#1

时间:2014-04-17 18:20:42

标签: android android-asynctask

我使用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);

    }

}

}

2 个答案:

答案 0 :(得分:1)

当您在usertext中致电null时,URLEncoder.encode似乎doInBackground

onActivityResult中,您首先开始您的任务,然后usertext设置一个值。这不会起作用,因为任务可能已经开始在AsyncTask的单独线程上运行。您可能希望在new GetBotResponse().execute();之后移动tvut.setText(usertext);行。

无论哪种方式,如果你不那么依赖共享变量,那可能会更好。在当前状态下,这非常容易出现并发问题,例如当用户连续多次快速点击时。这将导致多个任务同时运行,尝试读取和写入相同的变量,并可能产生不一致的结果。

GetBotResponse仅需要usertext作为输入,并生成str_usersaystr_botsaystr_convo_id作为输出。您可以usertext final GetBotResponse字段onPostExecute并在其构造函数中传递值。您还可以为这三个字符串创建一个包装类,并让任务返回一个实例,然后在onPostExecute中使用该实例。

通过这种方式,您可以摆脱这些共享变量,而不必在以后讨厌令人讨厌的并发问题。你仍然可以在tvbt中使用一些共享变量来处理用户界面(例如访问{{1}}),但你不会遇到麻烦:那时你又回到了GUI线程上。 ; - )

答案 1 :(得分:0)

似乎usertext为空,您只是在onActivityResult初始化