摩尔斯电码应用程序AsyncTask错误5

时间:2016-04-12 00:26:07

标签: java android android-asynctask

创建一个采用EditText值的应用程序,并将其转换为摩尔斯电码并输出音频,同时更改TextView背景颜色以执行任务。音频和textView改变颜色的目的是一起完成 我正在使用这个课程MorseTask.java,我认为这会给我带来最多的问题:

public class MorseTask extends AsyncTask<String, Integer, Void> {
private String translate;

@Override
protected Void doInBackground(String... params) {

    translate = params[0];
    int hold = 500;
    LinkedList<Signal> signals = MorseCode.genOnOffSchedule(translate, hold);
    long start = System.currentTimeMillis();

    while (!signals.isEmpty()){
        Signal sig = signals.removeFirst();
        boolean landed = false;
        while(!landed){
            landed = (System.currentTimeMillis() - start) > sig.getOnset();
            flashUI(sig);
        }
    }
    return null;
}
//TODO this
public void flashUI(Signal signal){
    int flashColor = Color.rgb(255, 255, 255);
    int oldColor = Color.rgb(2, 2, 2);
    if(signal.isOn()){
        publishProgress(1);
        MainActivity.textView2.setBackgroundColor(flashColor);
        int toneHrzt = 440;
        AudioTrack sound = AudioUtils.generateTone(toneHrzt, signal.getDuration());
        sound.play();
        //TODO this may need not null I'm not sure
        if(sound == null){
            sound.release();
        }
    }
    else{
        publishProgress(0);
        MainActivity.textView2.setBackgroundColor(oldColor);

    }
    try {
        Thread.sleep(signal.getDuration());
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }

}
//TODO add something here probably a void param
protected void onPostExecute(TextView result){
    //TODO reset the activity, possibly


}
}  
  • MorseCode.genOnOffSchedule(String, int)是一种基本上设置MorseCode序列/模式的方法。

  • 我不确定如何使用onPostExecute除了可能重置活动。

这是我的MainActivity以及我如何执行任务:

public class MainActivity extends AppCompatActivity {
public static TextView textView2;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    textView2 = (TextView)findViewById(R.id.textView2);
    final EditText message = (EditText)findViewById(R.id.editText);
    final Button translate = (Button)findViewById(R.id.button);
    translate.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String text = message.getText().toString();
            MorseTask transmit = new MorseTask();
            transmit.execute(text);
        }
    });
}

}

最后我的logcat错误:

04-11 19:45:45.191 7815-7937/MYDOMAIN E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #5
Process: MYDOMAIN, PID: 7815
                                                      java.lang.RuntimeException: An error occured while executing doInBackground()
                                                                          at android.os.AsyncTask$3.done(AsyncTask.java:304)
                                                                          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:818)
                                                                       Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
                                                                          at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6357)
                                                                          at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:909)
                                                                          at android.view.ViewGroup.invalidateChild(ViewGroup.java:4690)
                                                                          at android.view.View.invalidateInternal(View.java:11801)
                                                                          at android.view.View.invalidate(View.java:11737)
                                                                          at android.view.View.invalidateDrawable(View.java:15825)
                                                                          at android.widget.TextView.invalidateDrawable(TextView.java:5129)
                                                                          at android.graphics.drawable.Drawable.invalidateSelf(Drawable.java:368)
                                                                          at android.graphics.drawable.ColorDrawable.setColor(ColorDrawable.java:134)
                                                                          at android.view.View.setBackgroundColor(View.java:16184)
                                                                          at edu.ggc.amauldin.morsecode.MorseTask.flashUI(MorseTask.java:45)
                                                                          at edu.ggc.amauldin.morsecode.MorseTask.doInBackground(MorseTask.java:34)
                                                                          at edu.ggc.amauldin.morsecode.MorseTask.doInBackground(MorseTask.java:18)
                                                                          at android.os.AsyncTask$2.call(AsyncTask.java:292)
                                                                          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:818) 

1 个答案:

答案 0 :(得分:1)

These lines:

MainActivity.textView2.setBackgroundColor(flashColor);
...
MainActivity.textView2.setBackgroundColor(oldColor);

are being called in the flashUI() method, which you're calling from doInBackground(), which means they're happening on a separate thread. You cannot touch on-screen Views from any thread but the main thread.

Move those lines to the AsyncTask's onProgressUpdate() method, which runs on the main thread.