简体   繁体   中英

How do I get my app to not hang on device

I am new to android development and software programming in general and believe I have a threading issue in my app. What the app does is searches for two sets of results based on two queries to an api and stores each set of results in its own list. A new list is generated containing only the elements that are in both lists. The app runs in a virtual device on my desktop but hangs on my Galaxy Nexus. I am using arraylist for this but I am wondering if perhaps hashset would be faster at accomplishing this type of operation. Below is my main activity. getfirst and secondID are done in an asynctask as well as getfirst and secondtitle in order to prevent networkonmainthread exception. Is that the best way to thread this application? Thanks for any help.

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.totlayout);

    //set the UI elements
    searchOne = (EditText) findViewById(R.id.searchOne);
    searchTwo = (EditText) findViewById(R.id.searchTwo);

    findMovies = (Button) findViewById(R.id.findMovies);

    searchOne.setOnKeyListener(new View.OnKeyListener() {

        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            // TODO Auto-generated method stub
            //make person search url1
            final StringBuilder personSearchURLOne = new StringBuilder(getName.getName1(searchOne)); 
            searchURLOne = personSearchURLOne.toString();
            return false;
        }
    });

    searchTwo.setOnKeyListener(new View.OnKeyListener() {

        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            // TODO Auto-generated method stub
            //make person search url2
            final StringBuilder personSearchURLTwo = new StringBuilder(getName.getName2(searchTwo));
            searchURLTwo = personSearchURLTwo.toString();

            return false;
        }
    }); 
}
public void getData(String searchURLOne, String searchURLTwo){
    try{
        //get ID 1 
        idOne = new getFirstID().execute(searchURLOne).get();
        Log.d("JSONArray idOne", idOne.toString());

       //get ID 2
       idTwo = new getSecondID().execute(searchURLTwo).get();
       Log.d("JSONArray idTwo", idTwo.toString());

       //make credit search url1
       final StringBuilder creditURLOne = new StringBuilder(buildCreditURL.getCreditURLOne(idOne));
       final String creditOne = creditURLOne.toString(); 
       Log.d("creditOne contains", creditOne);

       //make credit search url2
       final StringBuilder creditURLTwo = new StringBuilder(buildCreditURL.getCreditURLTwo(idTwo));
       final String creditTwo = creditURLTwo.toString();

       //get array of tiles for credit url 1 
       titleOne = new getFirstTitle().execute(creditOne).get();
       Log.d("titleOne Contains", titleOne.toString());

       //get array of titles for credit url 2
       titleTwo = new getSecondTitle().execute(creditTwo).get();

       //parse out common films into new array 
       myCommonFilms = new ArrayList<String>(commonFilms.getCommonFilms(titleOne, titleTwo));
    }
    catch(InterruptedException e){
        e.printStackTrace();
    }catch(ExecutionException e){
        e.printStackTrace();
    }



}
public void displayResults(View view) throws InterruptedException, ExecutionException{
    //do something in response to button
    getData(searchURLOne, searchURLTwo);
    Intent intent = new Intent(this, DisplayResultsActivity.class).putStringArrayListExtra("myCommonFilmsList", myCommonFilms);
    startActivity(intent);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.totlayout, menu);
    return true;
}
}

I think it's the correct way : using AsyncTask is an easy way to prevent your app for freezing the UI.

But I don't really understand what the following line do.

idOne = new getFirstID().execute(searchURLOne).get();

Actually, I never see it before. Anyway, how many records are you managing in your ArrayList ? 10, 100, 1000, 1 000 000 ?

If you're working with a lot of records, your phone will take a certain amount of time to accomplish the operations and you'll not be able to reduce it. The only solution, if the set is too large, is to trying to reduce it maybe directly on your server or when you're building your ArrayList.

I'm not necessarily following where the AsyncTask is created and put into action but it seems like it would be a good idea to put the entire getData method on the AsyncTask. That aside, if it works on the and but not on the device my 1st suspicion would be network access. Make sure your device has access not only to the internet but to the service that it needs to run the remote query on. It's very common to misunderstand that phones cannot see the same host computers as our desktops can. Also, if you're phone is roaming on Wifi check that the Wifi network will allow the service to be accessed. Is the remote query service a web service? Is it a DBMS SQL call you are trying to run? does the query require a specific network port?

this one seems to block the UI thread:

   titleOne = new getFirstTitle().execute(creditOne).get();

better use a new thread for doing the long job , and once it finishes , notify the UI thread about the new data .

you can use asyncTask to make it easier for you . if you prefer the normal threads ,either use a handler (and use handler.post ) or use runOnUiThread once the thread has finished.

if you use a hanlder , don't forget to create it outside the of thread itself.

as a new android developer , you should watch the google IO videos . they can help a lot . watch videos from 2010 to 2012 .

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