“runOnUiThread”上的Android Thread / AsyncTask,ExceptionInInitializerError和RuntimeException

时间:2013-09-23 17:34:47

标签: android multithreading exception android-asynctask

我需要你帮助解决我遇到的两个错误

  1. 创建一个我正在创建文件的线程
  2. 文件后,执行AsyncTask将文件发送到服务器(multipart / form-data)
  3. 这是第一部分的样子:

    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”。但是该函数也应该从第一个函数中调用。

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

    或者我应该将“transferFileToServer”函数中的“AsyncTask”更改为Thread,因为我不进行任何UI操作?

    编辑:该方法从Async-Task

    开始
    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();
                }
            }   
    
        }
    
    }
    

1 个答案:

答案 0 :(得分:0)

删除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在没有线程或处理程序的情况下运行后台操作/逻辑的主要思想。

您不需要使用其他Thread包装AsyncTask并使用UI Thread绑定

从你的代码:

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

 ....

new Thread() {

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


 }.start()

}

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

这是一个问题。

从活动中开始AsyncTask