我正在为没有手电筒的手机编写一个手电筒应用程序,这是一个“屏幕灯”。我想要一个启用频闪灯功能的设置。然而,对于这种类型的“手电筒”,我认为最简单的方法是改变视图的背景。我在一个单独的线程中执行此操作,因为我使用SeekBar来获取strobelight应该闪存的速度。但是,我不断收到Thread无法访问View的错误,因为它不是创建它的Thread。有什么建议吗?
以下是onCreate()中包含的内容:
mSeekBar = (SeekBar) findViewById(R.id.seekBar);
mSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener(){
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
final Thread strober = new Thread(new Runnable(){
public void run(){
strobeLight();
}
});
if (mSeekBar.getProgress()>0) {
runOnUiThread(new Runnable() {
@Override
public void run() {
strober.start();
}
});
}
else {
runOnUiThread(new Runnable() {
@Override
public void run() {
strober.interrupt();
relLayout.setBackgroundColor(color.all_white);
}
});
}
}
public void onStartTrackingTouch(SeekBar seekBar) {}
public void onStopTrackingTouch(SeekBar seekBar) {}
});
这是strobeLight()方法:
public void strobeLight(){
boolean lightIsOn=true;
runOnUiThread(new Runnable() {
@Override
public void run() {
do {
if (lightIsOn){
relLayout.setBackgroundColor(color.all_black);
try { Thread.sleep(1000/(mSeekBar.getProgress()+2)); }
catch (InterruptedException e) {}
lightIsOn=false;
strobeActivated=true;}
else{
relLayout.setBackgroundColor(color.all_white);
try { Thread.sleep(1000/(mSeekBar.getProgress()+2)); }
catch (InterruptedException e) {}
lightIsOn=true; }
if (mSeekBar.getProgress()<1)
strobeActivated=false;
} while (strobeActivated);
relLayout.setBackgroundColor(color.all_white);
}
});
}
以下是上述代码的LogCat:
11-28 17:17:58.383: E/ActivityManager(16877): ANR in com.marshall.meadows182 (com.marshall.meadows182/.LightNoTorch), time=603431510
11-28 17:17:58.383: E/ActivityManager(16877): Reason: keyDispatchingTimedOut
11-28 17:17:58.383: E/ActivityManager(16877): Load: 1.53 / 1.62 / 1.62
11-28 17:17:58.383: E/ActivityManager(16877): CPU usage from 14662ms to 0ms ago:
11-28 17:17:58.383: E/ActivityManager(16877): 0.8% 16877/system_server: 0.4% user + 0.4% kernel / faults: 7 minor
11-28 17:17:58.383: E/ActivityManager(16877): 0% 14673/com.qikffc.android: 0% user + 0% kernel / faults: 151 minor
11-28 17:17:58.383: E/ActivityManager(16877): 0.2% 16957/com.android.systemui: 0.2% user + 0% kernel / faults: 1 minor
11-28 17:17:58.383: E/ActivityManager(16877): 0.1% 16999/com.android.phone: 0% user + 0% kernel
11-28 17:17:58.383: E/ActivityManager(16877): 0.1% 13/kondemand/0: 0% user + 0.1% kernel
11-28 17:17:58.383: E/ActivityManager(16877): 0% 68/rild: 0% user + 0% kernel / faults: 6 minor
11-28 17:17:58.383: E/ActivityManager(16877): 0% 14830/logcat: 0% user + 0% kernel
11-28 17:17:58.383: E/ActivityManager(16877): 0.1% 14868/com.marshall.meadows182: 0% user + 0% kernel / faults: 9 minor
11-28 17:17:58.383: E/ActivityManager(16877): 0% 24825/adbd: 0% user + 0% kernel
11-28 17:17:58.383: E/ActivityManager(16877): 0% 5446/com.google.android.apps.maps:NetworkLocationService: 0% user + 0% kernel
11-28 17:17:58.383: E/ActivityManager(16877): 0% 7839/wpa_supplicant: 0% user + 0% kernel / faults: 3 minor
11-28 17:17:58.383: E/ActivityManager(16877): 0% 17054/com.google.process.gapps: 0% user + 0% kernel / faults: 4 minor
11-28 17:17:58.383: E/ActivityManager(16877): 0% 25055/iqd: 0% user + 0% kernel
11-28 17:17:58.383: E/ActivityManager(16877): 2.7% TOTAL: 1.8% user + 0.8% kernel
11-28 17:17:58.383: E/ActivityManager(16877): CPU usage from 416ms to 935ms later with 99% awake:
11-28 17:17:58.383: E/ActivityManager(16877): 7.4% 16877/system_server: 0% user + 7.4% kernel / faults: 6 minor
11-28 17:17:58.383: E/ActivityManager(16877): 9.2% 16923/InputDispatcher: 1.8% user + 7.4% kernel
11-28 17:17:58.383: E/ActivityManager(16877): 3.8% TOTAL: 0% user + 3.8% kernel
答案 0 :(得分:2)
错误消息不言自明。不允许在创建它们的线程之外调用许多视图方法,称为UI线程。
问题是线
relLayout.setBackgroundColor(...);
在你的线程中运行。您应该在UI线程上运行它们,如下所示:
runOnUiThread(new Runnable() {
@Override
public void run() {
relLayout.setBackgroundColor(...);
}
});
答案 1 :(得分:0)
这是正常的,你不能在那里改变UI。我建议使用AsyncTask并在onPostExecute方法上更改UI。无论如何,如果您不想更改,则必须使用处理程序更改ui。