skip to Main Content

What I’m doing is make a activity to request JSON from an api.
I need the progress bar to show up during processing.
Here is my xml code

<?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>

And here is my activity

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();
            }
        }




    }

}

The toast works well, it will show up every time after clicking the button.
When I comment the progressBar.setVisibility(View.GONE) in runOnNewThreadfunction, the progress bar will show up but won’t disappear, but if I leave the setVisibility here, the bar will never show up.
What’s going on here?

3

Answers


  1. here you put you visibility gone code in background thread it wont work because view wont run in background thread you should give listener in ui thread

       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);
                }
            });
                }
    
    Login or Signup to reply.
  2. Looks like after your toast message you’ve selected the option to disappear your progress bar.

    progressBar.setVisibility(View.GONE);
    

    you could try using

    progressBar.setVisibility(View.VISIBLE);
    
    Login or Signup to reply.
  3. Your problem is that the thread that you create in runOnNewThread() is useless: you create a new Thread, start it and then wait until the thread completes. Instead of writing

        Thread thread = new Thread(runnableThread);
        thread.start();
        thread.join();
    

    you could just as well write

        runnableThread.run();
    

    it would have the same effect.

    Because you are blocking the UI thread with this you are calling progressBar.setVisibility(View.GONE); before the UI had time to show the progress bar.


    The solution is the let the new thread run independently:

    public void runOnNewThread(View view) throws InterruptedException {
        progressBar.setVisibility(View.VISIBLE);
        runnableThread runnableThread = new runnableThread();
        Thread thread = new Thread(runnableThread);
        thread.start();
    }
    

    And to move the Toast.makeText(...).show(); and progressBar.setVisibility(View.GONE); to the end of the independent task:

    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);
                });
            }
        }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search