【问题标题】:Android Thread / AsyncTask, ExceptionInInitializerError and RuntimeException on "runOnUiThread"“runOnUiThread”上的 Android 线程/AsyncTask、ExceptionInInitializerError 和 RuntimeException
【发布时间】:2013-09-23 17:34:47
【问题描述】:

我遇到两个错误需要您的帮助

  1. 创建一个线程,我正在创建一个文件
  2. 在文件内容之后,执行 AsyncTask 以将文件发送到服务器(multipart/form-data)

这就是第一部分的样子:

public void startResultTransfer(final int timestamp, final int duration, final String correction, final float textSize, final int age, final int switch_count, final Activity activity){

    synchronized(DataTransmission.class){ 

        new Thread() {
            public void run() {
                FileWriter fw = null;
                //1.Check if file exists
                File file = new File(FILE_PATH);
                if(!file.exists()){
                    //File does not exists, when we have to generate the head-line
                    try {
                        fw = new FileWriter(FILE_PATH);
                        fw.append("timestamp\tduration\tcorrection\ttext_size\tage\tswitch_count"); //Headline
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                //2. Write Result
                try {
                    if(fw == null)
                        fw = new FileWriter(FILE_PATH);
                    fw.append("\n"+String.valueOf(timestamp)+"\t");
                    fw.append(""+String.valueOf(duration)+"\t");
                    fw.append(""+correction+"\t");
                    fw.append(""+String.valueOf(textSize)+"\t");
                    fw.append(""+String.valueOf(age)+"\t");
                    fw.append(""+String.valueOf(switch_count)+"\t");
                    fw.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                //3. File Transfer
                if(isOnline(activity))
                    transferFileToServer(activity);
            }
        }.start();

    }
}

函数“transferFileToServer”如下所示:

public synchronized void transferFileToServer(Activity activity){
    String id = id(activity);
    File file = new File(FILE_PATH);

    if(id != null && file.exists()){
        final String url = URL+id;
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                TransmissionTask task = new TransmissionTask();
                task.execute(url);
            }
        });

    }

}

现在,我收到带有解释性消息的“ExceptionInInitializerError”

由 java.lang.RuntimeException 导致无法在未调用 Looper.prepare() 的线程内创建处理程序"

在“activity.runOnUiThread”行。

在第一个函数中,我需要在一些预先设置后调用“transferFileToServer”。但是该函数也应该从第一个函数中单独调用。

我是否应该在线程结束时实现一个 MessageHandler 来执行 AsyncTask? http://developer.android.com/reference/android/os/Looper.html

或者我是否应该将“transferFileToServer”函数中的“AsyncTask”更改为线程,因为我不做任何 UI 操作?

编辑:方法从异步任务开始

class TransmissionTask extends AsyncTask<String, Void, String> {

    public TransmissionTask() {

    }

    @Override
    protected String doInBackground(String... params) {
        synchronized(DataTransmission.class){
            try {

                HttpURLConnection urlConn;
                java.net.URL mUrl = new java.net.URL(params[0]);
                urlConn = (HttpURLConnection) mUrl.openConnection();
                urlConn.setDoOutput(true);
                urlConn.setRequestMethod("POST");

                String boundary = "---------------------------14737809831466499882746641449";
                String contentType = "multipart/form-data; boundary="+boundary;
                urlConn.addRequestProperty("Content-Type", contentType);

                DataOutputStream request = new DataOutputStream(urlConn.getOutputStream());
                request.writeBytes("\r\n--"+boundary+"\r\n");
                request.writeBytes("Content-Disposition: form-data; name=\"userfile\"; filename=\""+FILE_NAME+"\"\r\n");
                request.writeBytes("Content-Type: application/octet-stream\r\n\r\n");

                File myFile = new File(FILE_PATH);
                int size = (int) myFile.length();
                byte[] bytes = new byte[size];
                try {
                    BufferedInputStream buf = new BufferedInputStream(new FileInputStream(myFile));
                    buf.read(bytes, 0, bytes.length);
                    buf.close();
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } 
                request.write(bytes);
                request.writeBytes("\r\n--"+boundary+"--\r\n");

                request.flush();
                request.close();

                InputStream responseStream = new BufferedInputStream(urlConn.getInputStream());

                BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream));
                String line = "";
                StringBuilder stringBuilder = new StringBuilder();
                while ((line = responseStreamReader.readLine()) != null)
                {
                    stringBuilder.append(line).append("\n");
                }
                responseStreamReader.close();

                String response = stringBuilder.toString();
                responseStream.close();
                urlConn.disconnect();

                return response;

            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);

        if(result != null){
            if(result.toLowerCase().contains("erfolgreich")){
            //If successfull delete File
            File file = new File(FILE_PATH);
            file.delete();
            }
        }   

    }

}

【问题讨论】:

  • 虽然不是您的 current 错误背后的直接问题,但显然您正试图使用​​ runOnUiThread 将可能的网络操作放到 UI 线程上 - 与您应该做的完全相反,它在后台运行。
  • 嗨,克里斯,谢谢。我也是这么想的。好的,我会在没有异步任务的情况下做到这一点
  • 我们没有看到你的异步任务类的问题。可以发一下吗?

标签: android multithreading exception android-asynctask


【解决方案1】:

删除runOnUiThread

public synchronized void transferFileToServer(Activity activity){
String id = id(activity);
File file = new File(FILE_PATH);

if(id != null && file.exists()){
    final String url = URL+id;

      TransmissionTask task = new TransmissionTask();
      task.execute(url); 
  }
}

AsyncTask 的主要思想是在没有线程或处理程序的情况下运行后台操作/逻辑。

您不需要用额外的线程包裹AsyncTask 并与您所做的 UI 线程绑定

来自您的代码:

 public void startResultTransfer(/* ... */){

 ....

new Thread() {

    .....
     transferFileToServer(/* ... */); // its wrong!!! 
    ....


 }.start()

}

transferFileToServer 启动您的AsyncTask,您不是在主 UI 线程中而是在单个线程中运行它。

这是个问题。

从活动开始您的AsyncTask

【讨论】:

  • 谢谢,马克西姆。这是它最初的样子。但我得到了一个“ExceptionInInitializerError”。现在,我添加了一个附加功能,其中 im doing the data transfer. This function can now be started from the Thread in "startResultTransfer" and I changed the Async-Task in "transferFileToServer" to a Thread, where Im 也开始数据传输。
  • 你的设计好像太复杂了,一句话你想做什么?
  • 1.我想将信息添加到 txt 文件“startResultTransfer()”-> 之后,我需要将 txt 文件作为“multipart/form-data”发送到服务器,在成功传输 im deleting the file -&gt; If there is no internet-connection, I´m storing the information, as long as there is no internet connection in the txt-file. 2. If the internet connection exists again, im 检查是否txt 文件存在。如果 txt 文件存在,我会尝试将其重新发送到服务器。
  • 如果你运行我的例子,你从哪里得到ExceptionInInitializerError
  • 关于“TransmissionTask task = new TransmissioNTask(); task.execute(url)”
猜你喜欢
  • 2013-06-30
  • 2013-09-03
  • 2013-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多