-3

I have this code:

package com.jamie.translate;

import android.content.Context;
import android.net.Uri;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.EditText;
import android.widget.TextView;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import java.io.BufferedReader;
import java.net.URI;

/**
 * Created by Jamie on 25/6/2015.
 */
public class TranslateTextTask extends AsyncTask<TextView, Void, String> {
    TextView t;
    String result = "";
    String sourceText = "";
    String sourceLanguage = "";
    String resultLanguage = "";

    public TranslateTextTask(String _sourceText, String _sourceLanguage, String _resultLanguage) {
        this.sourceText = _sourceText;
        this.sourceLanguage = _sourceLanguage;
        this.resultLanguage = _resultLanguage;
    }

    protected void d(String tag, String errorMessage) {
        MainActivity.showNormalMessage(MainActivity.applicationContext, errorMessage);
    }

    @Override
    protected String doInBackground(TextView... params) {
        this.t = params[0];
        return GetTranslatedText();
    }

    final String GetTranslatedText() {
        Uri.Builder builder = new Uri.Builder();
        String langPair;
        URI uri = null;
        final HttpClient httpClient;
        final HttpGet request;
        final HttpResponse[] response = new HttpResponse[1];
        final BufferedReader reader = null;
        final String JSONResult = "";
        String translatedString;

        if(sourceText.length() > 500) {
            MainActivity.showErrorMessage(MainActivity.applicationContext, "Source text can only be max. 500 characters");
            return "";
        }

        d("Test", "Tag2");try {
            String x = ("en - English").substring(0, 2);
            String y = resultLanguage.substring(0, 2);

            langPair =
                    sourceLanguage.substring(0, 2)
                            + "|"
                            + resultLanguage.substring(0, 2);
        } catch (Exception e) {
            MainActivity.showErrorMessage(MainActivity.applicationContext, "Source language or result language invalid.");
            return "";
        }

        d("Test", "Tag3");try {
            uri = new URI(builder.scheme("http")
                    .authority("api.mymemory.translated.net")
                    .appendPath("get")
                    .appendQueryParameter("langpair", langPair)
                    .appendQueryParameter("q", sourceText)
                    .build()
                    .toString());
        } catch (Exception e) {
            MainActivity.showErrorMessage(MainActivity.applicationContext, "Failed to build HTTP request URL.");
            return "";
        }

        d("Test", "Tag4");try {
            httpClient = new DefaultHttpClient();
            request = new HttpGet();
            request.setURI(uri);
        } catch (Exception e) {
            MainActivity.showErrorMessage(MainActivity.applicationContext, "Failed to build HTTP request.");
            return "";
        }

        d("Test", "Tag5");try {
            // response = httpClient.execute(request);
            d("Test", "Tag6");try {
                response[0] = (httpClient.execute(request));
                return MainActivity.handleTranslateRequest(MainActivity.applicationContext, response[0]);
            } catch (Exception e) {
                MainActivity.showErrorMessage(MainActivity.applicationContext, e.toString());
                return "";
            }
        } catch (Exception e) {
            MainActivity.showErrorMessage(MainActivity.applicationContext, e.toString());
            // MainActivity.showErrorMessage(MainActivity.applicationContext, "Failed to complete HTTP request.");
            return "";
        }
    }

    protected void onPostExecute(String result) {
        t.setText(result);
    }
}

And I start this code by:

new TranslateTextTask(((EditText) findViewById(R.id.source)).getText(), translateSourceLanguage, translateResultLanguage).execute((EditText) findViewById(R.id.result));

Example values of values of variable in debug process include

((EditText) findViewById(R.id.source)).getText(): "Hi"
translateSourceLanguage: "en - English"
translateResultLanguage: "it - Italiano"

There was no internet connection problem. During debug process, I set enough breakpoints and found the force quit problem happened on this line:

String x = ("en - English").substring(0, 2);

What can I do to solve this problem? This seems to be a super-simple problem but can't stop it at all.

Edit

LogCat message:

06-25 18:41:04.318    9337-9534/com.jamie.translate E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
    Process: com.jamie.translate, PID: 9337
    java.lang.RuntimeException: An error occured while executing doInBackground()
            at android.os.AsyncTask$3.done(AsyncTask.java:300)
            at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
            at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
            at java.util.concurrent.FutureTask.run(FutureTask.java:242)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:841)
     Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
            at android.os.Handler.<init>(Handler.java:200)
            at android.os.Handler.<init>(Handler.java:114)
            at android.widget.Toast$TN.<init>(Toast.java:376)
            at android.widget.Toast.<init>(Toast.java:108)
            at android.widget.Toast.makeText(Toast.java:267)
            at com.jamie.translate.MainActivity.showNormalMessage(MainActivity.java:26)
            at com.jamie.translate.TranslateTextTask.d(TranslateTextTask.java:35)
            at com.jamie.translate.TranslateTextTask.GetTranslatedText(TranslateTextTask.java:60)
            at com.jamie.translate.TranslateTextTask.doInBackground(TranslateTextTask.java:41)
            at com.jamie.translate.TranslateTextTask.doInBackground(TranslateTextTask.java:21)
            at android.os.AsyncTask$2.call(AsyncTask.java:288)
            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:841)
JCCM
  • 127
  • 1
  • 11

1 Answers1

0

You must not touch UI (i.e. posting Toasts or update TextView etc) on your doInBackground(). If you need to update UI you need to either do this in onPostExecute() or use onProgressUpdate() if that would fit.

Marcin Orlowski
  • 72,056
  • 11
  • 123
  • 141