Marco D.
Marco D.

Reputation: 133

Android Studio Activity start delayed

I got a AsyncTask:

 package e.marco.swimcommit;


import android.os.AsyncTask;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;


public class News extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... strings) {
        final StringBuilder builder = new StringBuilder();
        final StringBuilder builder2 = new StringBuilder();
        {
            try {
                Document doc = Jsoup.connect("http://www.schwimmclub-schwandorf.de/index.php/8-home/56-infos-neuigkeiten").get();
                String title = doc.title();
                Elements links = doc.select("h2");
                Elements links2 = doc.select("h3");
                builder.append(title).append("\n");
                for (Element link : links) {
                    builder.append(link.text()).append("$");
                }
                for (Element link : links2) {
                    builder2.append(link.text()).append("$");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        String text = builder.toString() + "%" + builder2.toString();
        return text;
    }
}

and a onResume Methode in my MainActivity which set the returned text in a textview

  @Override
    protected void onResume()
    {
        super.onResume();
        try {
            eins.setText(new News().execute().get());
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

But if i start the App it shows me a white Screen until onResume Methode get the text and set it to the Textview. How is it possible to load the App show all other Elements like Buttons Background and so on without the delayed start? So that the Textview is blank until the onResume Methode get the Information and set it? Edit: Without blocking the UI

Upvotes: 0

Views: 85

Answers (3)

Puja Kamate
Puja Kamate

Reputation: 13

You can call asyncTask in oncreate method. And set the result in onProgressUpdate method.

@Override
protected void onProgressUpdate(String... text) {
    eins.setText.setText(text);    
}

Upvotes: 0

Raj Yadav
Raj Yadav

Reputation: 10798

As suggested by pz64, set the text in onPostExecute() method and call the AsyncTask() without calling get() method. get() method on AsyncTask makes task synchronous and also affects your UI.

public class News extends AsyncTask<String, Void, String> {

    @override
    protected void onPreExecute(){
         //initiate your loading views
    }

    @Override
    protected String doInBackground(String... strings) {
        final StringBuilder builder = new StringBuilder();
        final StringBuilder builder2 = new StringBuilder();
        {
            try {
                Document doc = Jsoup.connect("http://www.schwimmclub-schwandorf.de/index.php/8-home/56-infos-neuigkeiten").get();
                String title = doc.title();
                Elements links = doc.select("h2");
                Elements links2 = doc.select("h3");
                builder.append(title).append("\n");
                for (Element link : links) {
                    builder.append(link.text()).append("$");
                }
                for (Element link : links2) {
                    builder2.append(link.text()).append("$");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        String text = builder.toString() + "%" + builder2.toString();
        return text;
    }
    @override
    protected void onPostExecute(String response){
        //dispose loading views
        if(response != null){
            eins.setText(response);
        }else{
             //could not load
        }
    }
}

Call:

@Override
protected void onResume()
{
    super.onResume();
    new News().execute(); //do not call get method
}

Upvotes: 0

Son Truong
Son Truong

Reputation: 14193

AsyncTask is used to perform background operations and publish results on the UI thread. In your case you should put eins.setText into onPostExecute of AsyncTask.

Another problem is because the AsyncTask is a separate class so you need to define an interface to pass result back to MainActivity.

News

public class News extends AsyncTask<String, Void, String> {
    private WeakReference<OnNewsListener> mOnNewsListener;

    public void setOnNewsListener(OnNewsListener listener) {
        mOnNewsListener = new WeakReference<>(listener);
    }

    @Override
    protected String doInBackground(String... strings) {
        final StringBuilder builder = new StringBuilder();
        final StringBuilder builder2 = new StringBuilder();
        {
            try {
                Document doc = Jsoup.connect("http://www.schwimmclub-schwandorf.de/index.php/8-home/56-infos-neuigkeiten").get();
                String title = doc.title();
                Elements links = doc.select("h2");
                Elements links2 = doc.select("h3");
                builder.append(title).append("\n");
                for (Element link : links) {
                    builder.append(link.text()).append("$");
                }
                for (Element link : links2) {
                    builder2.append(link.text()).append("$");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        String text = builder.toString() + "%" + builder2.toString();
        return text;
    }

    @Override
    protected void onPostExecute(String text) {
        if (mOnNewsListener != null) {
            if (mOnNewsListener.get() != null) {
                mOnNewsListener.get().onNews(text);
            }
        }
    }

    public interface OnNewsListener {
        void onNews(String text);
    }
}

MainActivity

public class MainActivity extends AppCompatActivity implements News.OnNewsListener{
    TextView eins;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        eins = findViewById(R.id.eins);
    }

    @Override
    protected void onResume() {
        super.onResume();

        News news = new News();
        news.setOnNewsListener(this);
        news.execute();
    }

    @Override
    public void onNews(String text) {
        eins.setText(text);
    }
}

Upvotes: 2

Related Questions