困境 UI 主题或新主题
dilemma UI Thread or new Thread
我有一堆文本视图和按钮最初在 .xml 中设置为 GONE,我正在设置代码以在短时间内一个接一个地显示它们(使它们可见)。如果我使用 UI 线程,如果间隔长于大约 5 秒,我会冒 "Application not responding"(或 "ANR")的风险,但如果我创建新线程,则我必须使用
.getHandler().post(new Runnable() {
public void run() {
.setVisibility(View.VISIBLE);
}
它一直回到 UI 线程(在我的理解中),所以...那么拥有新线程有什么意义!?
有人可以对此进行解释和详细说明:)
xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/sv"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/textview_background"
android:text="Linija 1"
android:id="@+id/tv1"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/textview_background"
android:text="Linija 2"
android:id="@+id/tv2"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/textview_background"
android:text="Linija 3"
android:id="@+id/tv3"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/textview_background"
android:text="Linija 4"
android:id="@+id/tv4"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/textview_background"
android:text="Linija 5"
android:id="@+id/tv5"
android:visibility="gone"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/LL1"
android:visibility="gone">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/btn1"
android:text="Btn1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/btn2"
android:text="Btn2"/>
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/my_textview_background"
android:text="Linija 6"
android:id="@+id/tv6"
android:layout_gravity="end"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/my_textview_background"
android:text="Linija 7"
android:id="@+id/tv7"
android:layout_gravity="end"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/textview_background"
android:text="Linija 8"
android:id="@+id/tv8"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/textview_background"
android:text="Linija 9"
android:id="@+id/tv9"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/textview_background"
android:text="Linija 10"
android:id="@+id/tv10"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/textview_background"
android:text="Linija 11"
android:id="@+id/tv11"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/textview_background"
android:text="Linija 12"
android:id="@+id/tv12"
android:visibility="gone"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/LL2"
android:visibility="gone">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/btn3"
android:text="Btn3"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/btn4"
android:text="Btn4"/>
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/my_textview_background"
android:text="Linija 13"
android:id="@+id/tv13"
android:layout_gravity="end"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/my_textview_background"
android:text="Linija 14"
android:id="@+id/tv14"
android:layout_gravity="end"
android:visibility="gone"/>
</LinearLayout>
</ScrollView>
</RelativeLayout>
测试activity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_layout);
Thread mainThread = new Thread(
new Runnable() {
@Override
public void run() {
start_game();
}
}
);
mainThread.start();
}
public void start_game () {
Button btn1 = (Button) findViewById(R.id.btn1);
... btn4
TextView tv1 = (TextView) findViewById(R.id.tv1);
... tv14
LinearLayout LL1 = (LinearLayout) findViewById(R.id.LL1);
LinearLayout LL2 = (LinearLayout) findViewById(R.id.LL2);
show_line(tv1, 1000);
show_line(tv2, 1000);
show_line(tv3, 1000);
show_line(tv4, 1000);
show_line(tv5, 1000);
btnLL(LL1, btn1, btn2, tv6, tv7);
if (btn1.isPressed()) show_line(tv8, 1000);
if (btn2.isPressed()) show_line(tv9, 1000);
show_line(tv10, 1000);
show_line(tv11, 1000);
show_line(tv12, 1000);
public void show_line(final TextView tv, int duration) {
if (x) x=false;
viewArray[viewIndex++]= tv;
try {
Thread.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
tv.getHandler().post(new Runnable() {
public void run() {
tv.setVisibility(View.VISIBLE);
}
});
}
public void btnLL (final LinearLayout LL, Button btnLeft, Button btnRight, final TextView tvLeft, final TextView tvRight) {
linearArray[llIndex++]=LL;
LL.getHandler().post(new Runnable() {
public void run() {
LL.setVisibility(View.VISIBLE);
}
});
btnLeft.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
LL.getHandler().post(new Runnable() {
public void run() {
LL.setVisibility(View.GONE);
}
});
tvLeft.getHandler().post(new Runnable() {
public void run() {
tvLeft.setVisibility(View.VISIBLE);
}
});
x = true;
myViewArray[myViewIndex++]=tvLeft;
}
});
btnRight.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
LL.getHandler().post(new Runnable() {
public void run() {
LL.setVisibility(View.GONE);
}
});
tvRight.getHandler().post(new Runnable() {
public void run() {
tvRight.setVisibility(View.VISIBLE);
}
});
x = true;
myViewArray[myViewIndex++]=tvRight;
}
});
while (!x){}
}
这显然是一个奇怪/糟糕的设计案例。您只有 1 UI 个线程。如果您需要一次更新 UI 上的大量数据,也许您需要间隔刷新屏幕? IE 有一个 post runnable 可以调用自己,让它延迟 2 秒,读取您的状态并进行 UI 更改。如果你觉得有用我可以写出来..
更新post更多信息..
正在看这个。显然,这对您来说是错误的教程。老实说,我将投票结束这个问题,因为我认为它对其他人没有用。那就是说你的结构应该看起来更接近......虽然你可能对如何做到这一点感到困惑......如果你只是想让它们在用户按下按钮时显示和隐藏......摆脱线程。您根本不需要线程来执行此操作。对我来说,这个帖子看起来就像你在写游戏,而且游戏在不断循环。如果您正在等待用户按下按钮,则由侦听器完成。写一个线程也无济于事...
//HERE IS WHERE YOU DECLARE THE BUTTONS
Button btn1; //... btn4
TextView tv1; //... tv14
LinearLayout LL1;
LinearLayout LL2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_layout);
//HERE IS WHERE YOU SET YOUR BUTTONS
btn1 = (Button) findViewById(R.id.btn1);
tv1 = (TextView) findViewById(R.id.tv1);
LL1 = (LinearLayout) findViewById(R.id.LL1);
LL2 = (LinearLayout) findViewById(R.id.LL2);
//SET CLICK HANDLERS HERE
btnRight.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
LL.setVisibility(View.GONE);
tvRight.setVisibility(View.VISIBLE);
x = true;
myViewArray[myViewIndex++] = tvRight;
} );
btnLeft.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
LL.getHandler().post(new Runnable() {
public void run() {
LL.setVisibility(View.GONE);
}
});
tvLeft.getHandler().post(new Runnable() {
public void run() {
tvLeft.setVisibility(View.VISIBLE);
}
});
x = true;
myViewArray[myViewIndex++]=tvLeft;
}
});
Thread mainThread = new Thread(
new Runnable() {
@Override
public void run() {
start_game();
}
}
);
mainThread.start();
}
public void start_game () {
// guessing you would have a do while loop here?
show_line(tv1, 1000);
show_line(tv2, 1000);
show_line(tv3, 1000);
show_line(tv4, 1000);
show_line(tv5, 1000);
btnLL(LL1, btn1, btn2, tv6, tv7);
if (btn1.isPressed()) show_line(tv8, 1000);
if (btn2.isPressed()) show_line(tv9, 1000);
show_line(tv10, 1000);
show_line(tv11, 1000);
show_line(tv12, 1000);
}
public void show_line(final TextView tv, int duration) {
if (x) x=false;
viewArray[viewIndex++]= tv;
try {
Thread.sleep(duration); // look into post delay runnables.... thread sleep no.
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() { // we are on background thread. use runOnUiThread
@Override
public void run() {
tv.setVisibility(View.VISIBLE);
}
});
}
public void btnLL (final LinearLayout LL, Button btnLeft, Button btnRight, final TextView tvLeft, final TextView tvRight) {
linearArray[llIndex++]=LL;
runOnUiThread(new Runnable() { // we are on background thread. use runOnUiThread
@Override
public void run() {
LL.setVisibility(View.VISIBLE);
}
});
}
我有一堆文本视图和按钮最初在 .xml 中设置为 GONE,我正在设置代码以在短时间内一个接一个地显示它们(使它们可见)。如果我使用 UI 线程,如果间隔长于大约 5 秒,我会冒 "Application not responding"(或 "ANR")的风险,但如果我创建新线程,则我必须使用
.getHandler().post(new Runnable() {
public void run() {
.setVisibility(View.VISIBLE);
}
它一直回到 UI 线程(在我的理解中),所以...那么拥有新线程有什么意义!?
有人可以对此进行解释和详细说明:)
xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/sv"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/textview_background"
android:text="Linija 1"
android:id="@+id/tv1"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/textview_background"
android:text="Linija 2"
android:id="@+id/tv2"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/textview_background"
android:text="Linija 3"
android:id="@+id/tv3"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/textview_background"
android:text="Linija 4"
android:id="@+id/tv4"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/textview_background"
android:text="Linija 5"
android:id="@+id/tv5"
android:visibility="gone"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/LL1"
android:visibility="gone">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/btn1"
android:text="Btn1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/btn2"
android:text="Btn2"/>
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/my_textview_background"
android:text="Linija 6"
android:id="@+id/tv6"
android:layout_gravity="end"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/my_textview_background"
android:text="Linija 7"
android:id="@+id/tv7"
android:layout_gravity="end"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/textview_background"
android:text="Linija 8"
android:id="@+id/tv8"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/textview_background"
android:text="Linija 9"
android:id="@+id/tv9"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/textview_background"
android:text="Linija 10"
android:id="@+id/tv10"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/textview_background"
android:text="Linija 11"
android:id="@+id/tv11"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/textview_background"
android:text="Linija 12"
android:id="@+id/tv12"
android:visibility="gone"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/LL2"
android:visibility="gone">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/btn3"
android:text="Btn3"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/btn4"
android:text="Btn4"/>
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/my_textview_background"
android:text="Linija 13"
android:id="@+id/tv13"
android:layout_gravity="end"
android:visibility="gone"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/my_textview_background"
android:text="Linija 14"
android:id="@+id/tv14"
android:layout_gravity="end"
android:visibility="gone"/>
</LinearLayout>
</ScrollView>
</RelativeLayout>
测试activity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_layout);
Thread mainThread = new Thread(
new Runnable() {
@Override
public void run() {
start_game();
}
}
);
mainThread.start();
}
public void start_game () {
Button btn1 = (Button) findViewById(R.id.btn1);
... btn4
TextView tv1 = (TextView) findViewById(R.id.tv1);
... tv14
LinearLayout LL1 = (LinearLayout) findViewById(R.id.LL1);
LinearLayout LL2 = (LinearLayout) findViewById(R.id.LL2);
show_line(tv1, 1000);
show_line(tv2, 1000);
show_line(tv3, 1000);
show_line(tv4, 1000);
show_line(tv5, 1000);
btnLL(LL1, btn1, btn2, tv6, tv7);
if (btn1.isPressed()) show_line(tv8, 1000);
if (btn2.isPressed()) show_line(tv9, 1000);
show_line(tv10, 1000);
show_line(tv11, 1000);
show_line(tv12, 1000);
public void show_line(final TextView tv, int duration) {
if (x) x=false;
viewArray[viewIndex++]= tv;
try {
Thread.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
tv.getHandler().post(new Runnable() {
public void run() {
tv.setVisibility(View.VISIBLE);
}
});
}
public void btnLL (final LinearLayout LL, Button btnLeft, Button btnRight, final TextView tvLeft, final TextView tvRight) {
linearArray[llIndex++]=LL;
LL.getHandler().post(new Runnable() {
public void run() {
LL.setVisibility(View.VISIBLE);
}
});
btnLeft.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
LL.getHandler().post(new Runnable() {
public void run() {
LL.setVisibility(View.GONE);
}
});
tvLeft.getHandler().post(new Runnable() {
public void run() {
tvLeft.setVisibility(View.VISIBLE);
}
});
x = true;
myViewArray[myViewIndex++]=tvLeft;
}
});
btnRight.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
LL.getHandler().post(new Runnable() {
public void run() {
LL.setVisibility(View.GONE);
}
});
tvRight.getHandler().post(new Runnable() {
public void run() {
tvRight.setVisibility(View.VISIBLE);
}
});
x = true;
myViewArray[myViewIndex++]=tvRight;
}
});
while (!x){}
}
这显然是一个奇怪/糟糕的设计案例。您只有 1 UI 个线程。如果您需要一次更新 UI 上的大量数据,也许您需要间隔刷新屏幕? IE 有一个 post runnable 可以调用自己,让它延迟 2 秒,读取您的状态并进行 UI 更改。如果你觉得有用我可以写出来..
更新post更多信息..
正在看这个。显然,这对您来说是错误的教程。老实说,我将投票结束这个问题,因为我认为它对其他人没有用。那就是说你的结构应该看起来更接近......虽然你可能对如何做到这一点感到困惑......如果你只是想让它们在用户按下按钮时显示和隐藏......摆脱线程。您根本不需要线程来执行此操作。对我来说,这个帖子看起来就像你在写游戏,而且游戏在不断循环。如果您正在等待用户按下按钮,则由侦听器完成。写一个线程也无济于事...
//HERE IS WHERE YOU DECLARE THE BUTTONS
Button btn1; //... btn4
TextView tv1; //... tv14
LinearLayout LL1;
LinearLayout LL2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_layout);
//HERE IS WHERE YOU SET YOUR BUTTONS
btn1 = (Button) findViewById(R.id.btn1);
tv1 = (TextView) findViewById(R.id.tv1);
LL1 = (LinearLayout) findViewById(R.id.LL1);
LL2 = (LinearLayout) findViewById(R.id.LL2);
//SET CLICK HANDLERS HERE
btnRight.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
LL.setVisibility(View.GONE);
tvRight.setVisibility(View.VISIBLE);
x = true;
myViewArray[myViewIndex++] = tvRight;
} );
btnLeft.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
LL.getHandler().post(new Runnable() {
public void run() {
LL.setVisibility(View.GONE);
}
});
tvLeft.getHandler().post(new Runnable() {
public void run() {
tvLeft.setVisibility(View.VISIBLE);
}
});
x = true;
myViewArray[myViewIndex++]=tvLeft;
}
});
Thread mainThread = new Thread(
new Runnable() {
@Override
public void run() {
start_game();
}
}
);
mainThread.start();
}
public void start_game () {
// guessing you would have a do while loop here?
show_line(tv1, 1000);
show_line(tv2, 1000);
show_line(tv3, 1000);
show_line(tv4, 1000);
show_line(tv5, 1000);
btnLL(LL1, btn1, btn2, tv6, tv7);
if (btn1.isPressed()) show_line(tv8, 1000);
if (btn2.isPressed()) show_line(tv9, 1000);
show_line(tv10, 1000);
show_line(tv11, 1000);
show_line(tv12, 1000);
}
public void show_line(final TextView tv, int duration) {
if (x) x=false;
viewArray[viewIndex++]= tv;
try {
Thread.sleep(duration); // look into post delay runnables.... thread sleep no.
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() { // we are on background thread. use runOnUiThread
@Override
public void run() {
tv.setVisibility(View.VISIBLE);
}
});
}
public void btnLL (final LinearLayout LL, Button btnLeft, Button btnRight, final TextView tvLeft, final TextView tvRight) {
linearArray[llIndex++]=LL;
runOnUiThread(new Runnable() { // we are on background thread. use runOnUiThread
@Override
public void run() {
LL.setVisibility(View.VISIBLE);
}
});
}