创建一个采用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)
答案 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 View
s from any thread but the main thread.
Move those lines to the AsyncTask
's onProgressUpdate()
method, which runs on the main thread.