2017-05-29 190 views
0

我試圖從UI-Thread中讀取一個名爲PcmDataReaderRunnable中的SD卡中的文本文件,並相應地更新TextView statusTextView
我正在使用handler將消息從PcmDataReader傳遞給UI線程。

爲了能夠觀察statusTextView的更改,我已將Thread.sleep(5000)放入PcmDataReader

的問題是,在UI線程被阻塞,直到I/O &睡眠完成&最後的更新,即文件「文件讀取完成。。」僅在statusTextview上顯示。
我在這裏錯過了什麼?
以下是我的代碼:在另一個線程中調用Thread.sleep()時UI線程被阻塞



MainActivity.java:

package com.example.pcmreader; 

import android.Manifest; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Message; 
import android.support.v4.app.ActivityCompat; 
import android.support.v7.app.AppCompatActivity; 
import android.widget.TextView; 
import android.widget.Button; 


public class MainActivity extends AppCompatActivity implements View.OnClickListener{ 
    private TextView statusTextView ; 
    priavte Button updateButton; 

    private PcmDataReader pcmData = new PcmDataReader(); 
    private static Handler handler; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     handler = new Handler() 
     { 
      @Override 
      public void handleMessage (Message message) 
      { 
       String msg = (String) message.obj; 
       if (statusTextView != null) 
        statusTextView.setText(msg); 
      } 

     }; 

     setContentView(R.layout.main); 

     statusTextView= (TextView) findViewById(R.id.statusTextView); 

     ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.READ_EXTERNAL_STORAGE }, 100); 

    updateButton.setOnClickListener(this); 
    } 

    @Override 
    public void onClick(View view) 
    { 
    statusTextView.setText("Initiating Read .. "); 
     pcmData.run(); 

    } 

    public static Handler getHandler() 
    { 
     return handler; 
    } 
} 



PcmDataReader.java:

package com.example.pcmreader; 


import android.os.Bundle; 
import android.os.Environment; 
import android.os.Handler; 
import android.os.Message; 
import android.os.SystemClock; 
import android.util.Log; 
import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileReader; 
import java.io.IOException; 


public class PcmDataReader implements Runnable 
{ 
    private int [] samples = new int[6000]; 
    private int i; 
    private boolean completedReading; 
    private File sdcard = Environment.getExternalStorageDirectory(); 
    private File file = new File(sdcard,"rishav_log.txt"); 

    @Override 
    public void run() 
    { 

     i=0; 
     completedReading = false; 
     try 
     { 
      BufferedReader br = new BufferedReader(new FileReader(file)); 
      String line; 
      Handler uiHandler= MainActivity.getHandler(); 
      Message msg = uiHandler.obtainMessage(); 
      msg.obj="File openned, Reading data.."; 
      uiHandler.sendMessage(msg); 

      while ((line = br.readLine()) != null) 
       samples[i++]=Integer.parseInt(line); 

      Thread.sleep(5000); //dummy sleep to observe the update of textView in UI thead 
      br.close(); 
      completedReading = true; 

      msg = uiHandler.obtainMessage(); 
      msg.obj="File Reading Complete.."; 
      uiHandler.sendMessage(msg); 
     } 
     catch (IOException e) 
     { 
      Log.i("file read",e.getMessage()); 
     } 
    catch (InterruptedException e) 
    { 
      e.printStackTrace(); 
     } 
    } 

} 
+0

代碼中根本沒有多線程...... – Selvin

回答

3

調用運行的應該是單獨線程。

更換

pcmData.run(); 

Thread t1 =new Thread(pcmData); 
t1.start(); 
1

UI線程凍結,因爲你調用Thread.sleep()在同一個線程:

@Override 
public void onClick(View view) { 
    statusTextView.setText("Initiating Read .. "); 
    pcmData.run(); // PcmDataReader.run() will happen in the UI thread 

} 

修復的方法是比較容易的:

@Override 
public void onClick(View view) { 
    statusTextView.setText("Initiating Read .. "); 
    ExecutorService executor = Executors.newSingleThreadExecutor(); // this can come from somplace else. 
    // Actually, it better comes from someplac else. 
    executor.submit(pcmData); // this is how to run in in a background thread. 
    // executor.shutdown(); // this is necessary only if you create the executor in the same method. 
    // Otherwise, creating and killing background threads is a matter of your apps strategy. 
} 
相關問題