我正在做的是從 api 請求 JSON 的活動。我需要在處理程序中顯示進度條。這是我的xml代碼
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".WebService"
android:orientation="vertical">
<TextView
android:id="@ id/tips"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:singleLine="false"
android:text="Tips: Press the button to get a random web link, then click the widget to open that link in a web view." />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal">
<Button
android:id="@ id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:onClick="runOnNewThread"
android:text="Request Link"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ProgressBar
android:id="@ id/progressBar"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_gravity="center"
android:indeterminate="true"
android:visibility="visible"
android:layout_marginStart="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@ id/button"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.538"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@ id/result_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:singleLine="false"
android:text="" />
</LinearLayout>
這是我的活動
public class WebService extends AppCompatActivity {
private static final String TAG = "WebServiceActivity";
Handler handler = new Handler();
TextView resultText;
ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web_service);
resultText = (TextView) findViewById(R.id.result_textview);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
progressBar.setVisibility(View.INVISIBLE);
}
//button
public void runOnNewThread(View view) throws InterruptedException {
progressBar.setVisibility(View.VISIBLE);
runnableThread runnableThread = new runnableThread();
Thread thread = new Thread(runnableThread);
thread.start();
thread.join();
Toast.makeText(this, "Thread ends", Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.GONE);
}
class runnableThread implements Runnable{
@Override
public void run() {
JSONArray jArray;
try {
String url = NetworkUtil.validInput("https://api.publicapis.org/entries");
String resp = NetworkUtil.httpResponse(new URL(url));
JSONObject jObject = new JSONObject(resp);
jArray = jObject.getJSONArray("entries");
JSONObject resultObj = jArray.getJSONObject(new Random().nextInt(1421));
String API = resultObj.getString("API");
String description = resultObj.getString("Description");
String link = resultObj.getString("Link");
handler.post(()->{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
resultText.setText("");
resultText.append(API "\n");
resultText.append(description "\n");
resultText.append(link "\n");
});
} catch (NetworkUtil.MyException e) {
Toast.makeText(getApplication(),e.toString(),Toast.LENGTH_SHORT).show();
} catch (MalformedURLException e) {
Log.e(TAG,"MalformedURLException");
e.printStackTrace();
} catch (ProtocolException e) {
Log.e(TAG,"ProtocolException");
e.printStackTrace();
} catch (IOException e) {
Log.e(TAG,"IOException");
e.printStackTrace();
} catch (JSONException e) {
Log.e(TAG,"JSONException");
e.printStackTrace();
}
}
}
}
吐司效果很好,每次單擊按鈕后都會顯示。當我注釋progressBar.setVisibility(View.GONE)inrunOnNewThread函式時,進度條會顯示但不會消失,但是如果我將 setVisibility 留在這里,進度條將永遠不會出現。這里發生了什么?
uj5u.com熱心網友回復:
在這里,您將可見性消失的代碼放在后臺執行緒中它不會作業,因為視圖不會在后臺執行緒中運行您應該在 ui 執行緒中提供偵聽器
public void runOnNewThread(View view) throws InterruptedException {
progressBar.setVisibility(View.VISIBLE);
runnableThread runnableThread = new runnableThread();
Thread thread = new Thread(runnableThread);
thread.start();
thread.join();
// here is the problem Progress bar is a view , vie canton run in background thread
getActivity().runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(this, "Thread ends", Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.GONE);
}
});
}
uj5u.com熱心網友回復:
看起來在您的吐司訊息之后,您選擇了消失進度條的選項。
progressBar.setVisibility(View.GONE);
你可以嘗試使用
progressBar.setVisibility(View.VISIBLE);
uj5u.com熱心網友回復:
您的問題是您創建的執行緒runOnNewThread()是無用的:您創建一個新的Thread,啟動它,然后等到執行緒完成。而不是寫
Thread thread = new Thread(runnableThread);
thread.start();
thread.join();
你也可以寫
runnableThread.run();
它會產生同樣的效果。
progressBar.setVisibility(View.GONE);因為你在 UI 有時間顯示進度條之前呼叫了這個你正在呼叫的 UI 執行緒。
解決方案是讓新執行緒獨立運行:
public void runOnNewThread(View view) throws InterruptedException {
progressBar.setVisibility(View.VISIBLE);
runnableThread runnableThread = new runnableThread();
Thread thread = new Thread(runnableThread);
thread.start();
}
Toast.makeText(...).show();并將and移動progressBar.setVisibility(View.GONE);到獨立任務的末尾:
class runnableThread implements Runnable {
@Override
public void run() {
JSONArray jArray;
try {
// I didn't include all the code here
} catch (NetworkUtil.MyException e) {
WebService.this.runOnUiThread(() ->
Toast.makeText(getApplication(), e.toString(), Toast.LENGTH_SHORT).show()
);
// I also didn't include all the catch clauses
} finally {
WebService.this.runOnUiThread(() -> {
Toast.makeText(WebService.this, "Thread ends", Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.GONE);
});
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/439056.html
