简体   繁体   中英

Android: Why won't this code run in onCreate, or how can I make it work without a thread?

I have this piece of code that runs alright when I put it in Eclipse, but for some reason it does not want to execute when I put it in an activity's onCreate method in Android studio.

Here is the code:

public class ItemListView extends AppCompatActivity{
    String itemURL;
    int listSize;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_item_list_view);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

          Bundle itemData = getIntent().getExtras();
        if(itemData==null){
            return;
        }

        //Gets URL from search bar
        itemURL = itemData.getString("itemURL");

        try {
            Document doc = Jsoup.connect("https://www.amazon.com/s/ref=nb_sb_ss_c_1_6?url=search-alias%3Daps&field-keywords=rx+390&sprefix=rx+390%2Caps%2C166&crid=2MTUBA4KGNY06").get();
            String link = doc.select("h2#s-result-count").first().text();
            System.out.println(link);
            System.out.println(link.substring(1));
            if (link.substring(1, 2).equals("-")) {
                System.out.println("run1");
                listSize = Integer.parseInt(link.substring(2, 3));
                System.out.println(listSize);
                try {
                    listSize = Integer.parseInt(link.substring(2, 4));
                    System.out.println(listSize);
                } catch (Exception e) {
                }
            } else {
                System.out.println("run2");
                listSize = Integer.parseInt(link.substring(0, 1));
                System.out.println(listSize);
                try {
                    listSize = Integer.parseInt(link.substring(0, 2));
                    System.out.println(listSize);
                } catch (Exception e) {
                }
            }
            } catch (Exception e) {
        }

        System.out.println("listSize: " +listSize);
        ...
    }
}

I need listSize to create a variable array depending on the URL, but when I print the value to make sure it's working it always gives me 0. I have tried running the code in a separate Java Class with AsyncTask and it works, but by the time the code executes in onPostExecute, it's too late since the class above has already tried to initialize the array.

Any advice would be appreciated, thanks!

What you need is a callback to allow you to initialize variable onPostExecute :

interface OnCallCompleteCallBack {
    void onCallComplete(int listSize);
}

In your AsyncTask do this:

public class MyTask extends AsyncTask < ... > {
    // Maintain a ref to callback
    OnCallCompleteCallBack callback;

    MyTask(OnCallCompleteCallBack callback) {
        this.callback = callback;
    }

    ...

    @Override
    protected void onPostExecute(Void aVoid) {
        if (callback != null) {
            callback.onCallComplete(listSize);
        }
    }
}

Make your Activity implement OnCallCompleteCallBack and start the AsyncTask like this:

new MyTask(this).execute();

You can then use the value inside your activity's implementation of onCallComplete()

Before I answer, just a few observations:

  • Naming your activity ItemListView seems wrong (an Activity is not a View ).

  • You should never perform networks calls on the UI thread.

  • If you want to log, you should use Log instead of System.out.println() .

And now to the answer. You should execute the code that fetches the data in an AsyncTask (as you mentions it works). Once the data is fetched, you should update array and at that point update the UI in onPostExecute() .

Android works pretty well using the MVC (Model-View–Controller) pattern and your problem is a classic case where you need to update the model using data from the server and update the views accordingly. The activity represents controller in this case.

Please go through the topic in android developer site Android Developer , Read the section "Introducing Network Operations on a Separate Thread" - To avoid creating an unresponsive UI, don't perform network operations on the UI thread. By default, Android 3.0 (API level 11) and higher requires you to perform network operations on a thread other than the main UI thread; if you don't, a NetworkOnMainThreadException is thrown.

Thanks Ashish

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM