简体   繁体   中英

How to make onStart() method wait till the onCreate() method completes

I have an AsyncTask running from the onCreate() method of my Activity which fetches a list from mysql database.
In the onStart() method, I call the methods to start some animation.

I want these animations to be started only after the list is fetched.
Ie: after the completion the AsyncTask .

I know I can start animations in the onPostExecute() method of the AsyncTask object.
But I want these animations to be started every time the Activity becomes visible.

It should be something like:

FirstActivity (ListFetches and Animation Starts).
SecondActivity to FirstActivity (Animation Starts, list already fetched).

Below is my code

public class FirstSelection extends ActionBarActivity {
    Activity context;
    HttpPost httppost;
    StringBuffer buffer;
    HttpResponse response;
    HttpClient httpclient;
    ProgressDialog pd;
    CustomAdapter adapter;
    ListView listProduct;
    ArrayList<String> records;
    Intent i;
    Intent j;
    Intent k;
    double version;
    double oldVer = 1.0;
    String downloadlink;
    DownloadManager dm;
    private long enqueue;
    private Toolbar toolbar;
    ValueAnimator colorAnimation;
    FrameLayout myframe;
    ValueAnimator statusAnim;
    String[] menu;
    DrawerLayout dLayout;
    ListView dList;
    ArrayAdapter<String> dadapter;
    ImageView image;
    Animation anim;


    protected void onCreate(Bundle savedInstanceState) {
   //TODO Auto-generated method stub
   super.onCreate(savedInstanceState);
   setContentView(R.layout.first_selection);
   toolbar = (Toolbar) findViewById(R.id.new_tool);
   myframe = (FrameLayout)findViewById(R.id.myframe);
   menu = new String[]{"Refresh","Report Broken Link","Request songs"};
   dLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
   dList = (ListView)findViewById(R.id.navList);
   image = (ImageView)findViewById(R.id.loader);
   anim = AnimationUtils.loadAnimation(this, R.anim.myanim);
   image.startAnimation(anim);
   dadapter = new ArrayAdapter<String>(this,R.layout.drawer_list_item,menu);
   dList.setAdapter(dadapter);
    setSupportActionBar(toolbar);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
       Window w = getWindow(); // in Activity's onCreate() for instance
       w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
       w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
   }
   context=this;
   records=new ArrayList<String>();
   listProduct=(ListView)findViewById(R.id.product_list);
   i = new Intent(this, ReportActivity.class);
   j = new Intent(this, RequestActivity.class);
   k = new Intent(this, AboutDeveloper.class);
   BackTask bt=new BackTask();
   bt.execute();
   adapter=new CustomAdapter(context, R.layout.list_item_first,R.id.pro_name, records);
   listProduct.setAdapter(adapter);
   listProduct.setOnItemClickListener(new OnItemClickListener(){
       @Override
       public void onItemClick(AdapterView<?> arg0, View v, int position, long id){

           Intent songIntent = new Intent(getApplicationContext(), SecondSelection.class);
           startActivity(songIntent);

       }

   });

 //Animation for Action Bar

   Integer colorFrom = getResources().getColor(R.color.first);
   Integer colorTo = getResources().getColor(R.color.last);
   colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
   colorAnimation.addUpdateListener(new AnimatorUpdateListener() {

       @Override
       public void onAnimationUpdate(ValueAnimator animator) {
           toolbar.setBackgroundColor((Integer)animator.getAnimatedValue());
       }

   });


   //Animation for Status Bar

   Integer colorFirst = getResources().getColor(R.color.begin);
   Integer colorLast = getResources().getColor(R.color.end);
   statusAnim = ValueAnimator.ofObject(new ArgbEvaluator(), colorFirst, colorLast);
   statusAnim.addUpdateListener(new AnimatorUpdateListener() {

       @Override
       public void onAnimationUpdate(ValueAnimator animator) {
           myframe.setBackgroundColor((Integer)animator.getAnimatedValue());
       }

   });

   //Start the Animations after fetching the list.
   //After executing the bt.execute()

   }

    @Override
    public void onBackPressed() {
        if (dLayout.isDrawerOpen(dList)) {
           dLayout.closeDrawer(dList);
        } 

        else{
            doExit();
        }
    }


    /*@Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        if (keyCode == KeyEvent.KEYCODE_BACK) {

            doExit();
        }

        return super.onKeyDown(keyCode, event);
    }**/

    private void doExit() {

        AlertDialog.Builder alertDialog = new AlertDialog.Builder(
                FirstSelection.this);

        alertDialog.setPositiveButton("Yes", new OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                finish();
            }
        });

        alertDialog.setNegativeButton("No", null);

        alertDialog.setMessage("Do you want to exit?");
        alertDialog.setTitle("something");
        alertDialog.show();
    }

    @Override
    public void onStart() {
        super.onStart();
        //These are my animations
        statusAnim.setDuration(800);
        colorAnimation.setDuration(1300);
        colorAnimation.start();
        statusAnim.start();

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        return super.onOptionsItemSelected(item);
    }

    // background process to make a request to server and list product
    // information
    private class BackTask extends AsyncTask<Void, Void, Void> {
        protected void onPreExecute() {
            super.onPreExecute();
        //  pd = new ProgressDialog(context);
        //  pd.setTitle("Retrieving data");
        //  pd.setMessage("Please wait.");
        //  pd.setCancelable(true);
        //  pd.setIndeterminate(true);
        //  pd.show();

        }

        protected Void doInBackground(Void... params) {

            InputStream is = null;
            String result = "";
            try {

                records.clear();
                httpclient = new DefaultHttpClient();
                httppost = new HttpPost(
                        "somelink");
                response = httpclient.execute(httppost);
                HttpEntity entity = response.getEntity();
                is = entity.getContent();

            } catch (Exception e) {

                if (pd != null)
                    pd.dismiss(); // close the dialog if error occurs
                Log.e("ERROR", e.getMessage());

            }

            // convert response to string
            try {
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(is, "utf-8"), 8);
                StringBuilder sb = new StringBuilder();
                String line = null;
                while ((line = reader.readLine()) != null) {
                    sb.append(line + "\n");
                }
                is.close();
                result = sb.toString();
            } catch (Exception e) {
                Log.e("ERROR", "Error converting result " + e.toString());

            }

            // parse json data
            try {

                JSONArray jArray = new JSONArray(result);
                for (int i = 0; i < jArray.length(); i++) {
                    JSONObject json_data = jArray.getJSONObject(i);
                    String record = json_data.getString("context") + "__"
                            + json_data.getDouble("version");
                    version = json_data.getDouble("version");
                    downloadlink = json_data.getString("dlink");
                    records.add(record);

                }

            } catch (Exception e) {
                Log.e("ERROR", "Error pasting data " + e.toString());

            }

            return null;
        }

        protected void onPostExecute(Void result) {

        //  if (pd != null)
        //      pd.dismiss();// close dialog
            image.clearAnimation();
            image.setVisibility(View.GONE);
            adapter.notifyDataSetChanged();// notify the ListView to get new
                                            // records

            // statusAnim.setDuration(500);
            // statusAnim.start();

            // colorAnimation.setDuration(1000);
            // colorAnimation.start();

            if (oldVer < version) {
                ifUpdateAvailable();
            }
        }

        private void ifUpdateAvailable() {

            AlertDialog.Builder alertDialog = new AlertDialog.Builder(
                    FirstSelection.this);

            alertDialog.setPositiveButton("Yes", new OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {

                    dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
                    Request request = new Request(Uri.parse(downloadlink));
                    request.setDestinationInExternalPublicDir("/Download",
                            "Something_v1_1.apk");
                    enqueue = dm.enqueue(request);

                }
            });

            alertDialog.setNegativeButton("Later", null);

            alertDialog
                    .setMessage("A new version of something is available for download. Do you want to update now?");
            alertDialog.setTitle("something");
            alertDialog.show();

        }

        BroadcastReceiver receiver = new BroadcastReceiver() {

            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();

                if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
                    long downloadId = intent.getLongExtra(
                            DownloadManager.EXTRA_DOWNLOAD_ID, 0);
                    Query query = new Query();
                    query.setFilterById(enqueue);
                    Cursor c = dm.query(query);
                    if (c.moveToFirst()) {
                        int columnIndex = c
                                .getColumnIndex(DownloadManager.COLUMN_STATUS);
                        if (DownloadManager.STATUS_SUCCESSFUL == c
                                .getInt(columnIndex)) {

                            String uriString = c
                                    .getString(c
                                            .getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));

                        }
                    }
                }
                registerReceiver(receiver, new IntentFilter(
                        DownloadManager.ACTION_DOWNLOAD_COMPLETE));

            }
        };

    }
}

You dont need to do that. OnStart() will be called only after onCreate() is completed if activity is getting created for first time. These methods are called in serial order by android framework.

What you can do here is start a repeating timer in onStart() function which checks if AsyncTask is completed or not. As soon as it completes you can start your animation. You should stop this timer in onStop() method of your activity.

I believe the correct way to do this is to make the methods synchronized. Do this to both of the methods and they should wait for the other to finish before running the other:

method(){
  synchronized(this){
     //code
  }
}

You can read about it here: http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html

When I did this it worked for me when I have two threads calling separate methods in the same class.

A crude way to solve the problem would be to create a private boolean and set it to true when the onCreate() method is called and then set it to false when onCreate() finishes. In the onStart() you can have it return if the boolean is true or create a while loop like this: while(boolean){}

I am sure there is a much better way to do this, but at least this works.

If possible, you could just call the onStart() method at the end of the onCreate()

In your situation you cant hold onCreate() because AsyncTask doInBackground() method runs in worker thread.

Suggested : 1.

  1. onCreate() : Run AsyncTask

  2. onStart() check the AsyncTask status, whether its completed its task or not. After completing in onPostExecte() method start animation. 3.

  3. When you come back from the SecondActivity if [ onStart() ] AsyncTask is completed its task it start animation.

Example

public class MyActivity extends Activity {
    BackTask backTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // start AsyncTask
        backTask = new BackTask();
        backTask.execute();

    }

    @Override
    protected void onStart() {
        super.onStart();
        if (backTask.getStatus() == Status.FINISHED) {
            doAnimation();
        }
    }

    private void doAnimation() {
        // start animations
    }

    class BackTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... params) {
            // do web stuff
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);

            // fetches data now start anim
            doAnimation();

        }

    }

}

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