0

I am trying to load some data in the main activity layout from the database, while this happens I want to show the user a dialog in the popup. I have tried using thread and also async task but still the screen freezes while the data is being loaded and finally when it completes then it displays my popup. I want the dialog to display simultaneously with data load. below is the function from main activity that loads the data and calls the async task.

public void call_itemdisplay(final String bookid)
   {
      new waitAsync().execute();
      //load data from DB below
        }

The async task that starts a new activity

public class waitAsync extends AsyncTask<Void, Void, Void> {
    @Override
   protected Void doInBackground(Void... params) {
    try {
        Intent i = new Intent(MainActivity.mCon, waitActivity.class);
        MainActivity.mCon.startActivity(i);

    } catch (Exception e) {
        e.printStackTrace();
    }
        return null;
        }


}

The Popup Activity that is started by the async task

public class waitActivity extends Activity {
    static waitActivity wact;
    public static Context wcon;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        wact=this;

        setContentView(R.layout.activity_wait);
    }

}

Need help in showing the POPup activity in the UI while data loads in the main activity. Currently the screen freezes while loading data and then show all together after loading is complete

EDITED with new changes: The async task

public class waitAsync extends AsyncTask<String, Void, String> {
    ResultSet rs=null;
   private ProgressDialog processingDialog;
    static Connection conn=null;
    Statement stmt;
   // waitThread wt= new waitThread();
    @Override
    protected void onPreExecute() {
      //  ProgressDialog processingDialog;
        super.onPreExecute();
        processingDialog = new ProgressDialog(MainActivity.mCon);
        processingDialog.show();
        processingDialog.setContentView(R.layout.activity_wait);
        //processingDialog.setMessage("Loading...");

    }
    @Override
   protected String doInBackground(String... params) {
        try {


            String driver = "net.sourceforge.jtds.jdbc.Driver";
            String ip = "mfb.dfsdfsdf.ap-north-1.rds.amazonaws.com";
            String classs = "net.sourceforge.jtds.jdbc.Driver";
            String db = "MyDatabase";
            String un = "xxxwww";
            String password = "xxxxxx";
            Class.forName(classs);

            String ConnURL = null;
            ConnURL = "jdbc:jtds:sqlserver://" + ip + ";"
                    + "databaseName=" + db + ";user=" + un + ";password="
                    + password + ";";
            conn = DriverManager.getConnection(ConnURL);

            stmt = conn.createStatement(
                    ResultSet.TYPE_SCROLL_INSENSITIVE,
                    ResultSet.CONCUR_READ_ONLY);
            rs=stmt.executeQuery(params[0]);
            int size = 0;


            //conn.close();
            MainActivity.getdata=rs;
            MainActivity.flag=1;
            //Thread.sleep(5000);
        } catch (Exception e)
        {
            Log.w("Error connection", "" + e.getMessage());
        }
        return null;
        }
    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        processingDialog.dismiss();
      //  wt.interrupted();


    }



}

The call of async task from Main_Activity

Getdata(String bookid)
{
  String SQL="Select eb.book_name,eb.AuthorID,ma.Name,eb.GenreID_M,eb.GenreID_D,gm.Genre_MN+'- '+gd.Genre_DN as Genre,isnull(eb.pubDate,'') pubDate,isnull(eb.book_Loc,'') book_Loc,\n" +
                    " eb.Price,eb.ico_Loc,eb.Descrip from Master_ebook eb inner join Master_Author ma on eb.AuthorID=ma.Author_ID\n" +
                    " inner join Master_Genre_M gm on eb.GenreID_M=gm.Genre_MID\n" +
                    "inner join Master_Genre_D gd on eb.GenreID_D= gd.Genre_DID where eb.bookID=" + bookid;


            new waitAsync().execute(SQL);

            int c=0;
            while(MainActivity.flag==0)
            {
                c++;
            }

            if(MainActivity.flag==1)
            {
                MainActivity.flag=0;
                //processingDialog.dismiss();
            }

            ResultSet rs=MainActivity.getdata;
}
BonnY Dutt
  • 21
  • 1
  • 6

3 Answers3

1

In your AsyncTask,

  • Use onPreExecute to show progress dialog
  • Load data in doInBackground, this method will be called on worker thread
  • Hide dialog in onPostExecute

    ... AsyncTask<String, String, String>() {
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                // show dialog
            }
        // UPDATE
        @Override
        protected void onProgressUpdate(String... values) {
            super.onProgressUpdate(values);
           // this method will be called when you call
          //  publishProgress from doInBackground.
        }       
            @Override
            protected String doInBackground(String[] params) {
                // load data and return
               // this data will passed to onPostExecute
                publishProgress(param); // call onProgressUpdate
                return null;
            }
    
            @Override
            protected void onPostExecute(String o) {
                super.onPostExecute(o);
                // hide dialog
            }
    }
    

Here are few links, you can find useful in achieving your goal

Community
  • 1
  • 1
mallaudin
  • 4,235
  • 3
  • 29
  • 60
  • I tried the way you suggested. the problem is in doInBackground method when I try to updated the layout elements (Textview, ImageView others grids etc) with the data from the database I have this error. "Only the original thread that created a view hierarchy can touch its views." how can solve this? – BonnY Dutt Nov 21 '16 at 10:40
  • You should only update layout in `onPreExecute` or `onPostExecute` method call. I have mentioned this explicitly. You can update layout from UI thread only. `doInBackground` will be called on background thread. When you return from `doInBackground` pass any data you require, and use it in `onPostExecute` – mallaudin Nov 21 '16 at 10:42
  • Well, What you said was right and it helps to some extent.. but my final goal is to load data to the layout elements in the background while displaying the progress Dialog. But thanks for helping so far – BonnY Dutt Nov 21 '16 at 11:26
  • You can use `onProgressUpdate` to update layouts and then call it from `doInBackground` like `publishProgress`. Note this will also call on UI thread, so it's ok here to update your layouts. – mallaudin Nov 21 '16 at 11:30
  • @BonnYDutt I have updated my answer. Please have a look. – mallaudin Nov 21 '16 at 11:34
  • i tried the way you stated but still my progress dialog doesn't show immediately while the async task fetches data from the DB. you can see my edited code above. Can you suggest something that will display a progress dialog immediately on button click.. In the current scenario the screen freezes while its fetching data. Once fetched then it moves on to the next screen, but it doesn't show my progress dialog in the meanwhile. – BonnY Dutt Nov 23 '16 at 06:57
  • what are you doing? tell us in detail. You have written this comment `//load data from DB below` after calling async task. I don't understand what are you doing. – mallaudin Nov 23 '16 at 17:13
  • I cannot explain in detail here. It gets too long. but i have created another question for this with your suggested changes by putting the data load in "doinbackground" method and the progress dialog in "On Pre Execute" method of the asyn task. can you please check this http://stackoverflow.com/questions/40762054/need-help-in-showing-the-popup-dialog-in-the-ui-while-data-loads-in-background-a/40762505?noredirect=1#comment68750575_40762505 – BonnY Dutt Nov 24 '16 at 04:45
0

You can show your dialog like this. onPreExecute() method will call first show your dialog in this method. then doInBackground and after completion of background task in doInBackground() method, it will pass its result to onPostExecute() where you can dismiss you loading dialog.

class BackgroundTask extends AsyncTask<Void, Void, String>
{
    ProgressDialog progressDialog;

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

        progressDialog = new ProgressDialog(mContext);
        progressDialog.setMessage("Loading...");
        progressDialog.show();
    }

    @Override
    protected String doInBackground(Void... params) {

        //do your task here;

        return null;
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        progressDialog.dismiss();
    }
}
Vishal Chhodwani
  • 2,457
  • 5
  • 24
  • 37
  • I tried the way you suggested. the problem is in doInBackground method when I try to updated the layout elements (Textview, ImageView others grids etc) with the data from the database I have this error. "Only the original thread that created a view hierarchy can touch its views." how can solve this? – BonnY Dutt Nov 21 '16 at 10:38
  • Right, You can not update UI inside the doInBackground method. it is only for Non-UI task. all UI task should be done in onPostExecute() method. – Vishal Chhodwani Nov 21 '16 at 10:43
0

You have to first use onPreExecute() method in order to show dialog , and then fetch your data from databse in doInBackground() method, in following code snippet I have showned how you can return the data fetched from DB to onPostExecute() method which you can further process, and at last you just need to dismiss() the dialog box in onPostExecute(), and launch the next activity.

   private class waitAsync extends AsyncTask<Void, Void, String[]> {  
        private ProgressDialog processingDialog;
        Context cnt = null;
            waitAsync(Context cnt)
             {
              this.cnt = cnt;
              }
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            // Showing progress dialog
            processingDialog = new ProgressDialog(cnt);
            processingDialog.setMessage("Loading...");
            processingDialog.show();
        }

        @Override
        protected String[] doInBackground(Void... arg0) {
           //load data from DB below
            return null;
        }

        @Override
        protected void onPostExecute(String[] result) {
            super.onPostExecute(result);
            // Dismiss the progress dialog
            processingDialog.dismiss();
            try {
            Intent i = new Intent(cnt, waitActivity.class);
            cnt.startActivity(i);

            } catch (Exception e) {
             e.printStackTrace();
           }
        }

    }

You can call this by simply calling asyc task, and this will be done in background so, this should work:

 // Calling async task to fetch data from DB
   new waitAsync (context).execute();
U.Swap
  • 1,723
  • 4
  • 19
  • 35