0

I've got an app that makes API calls when the user logs in, I've got two classes, one that Pushes to the API and one that Pulls from it. I've also got an asyncTask on my LogIn Activity which handles the network connection. When the network connection starts I have a view switcher to switch the view to a progress loader and a textview, the textview is used to display stuff like "Connecting", "Downloading Data", ect.

The problem is my API Push and Pull methods are stored in different classes and the LogIn AsyncTask simply calls them, it all works except for updating the TextView to let the user know the progress.

In the LogIn activity, I have this method, which changes the textview info to whichever number is passed to it.

public void updateProgress(int i) {
        switch (i) {
            case 0:
                loadInfo.setText(R.string.log_in_thread_Connecting);
                break;
            case 1:
                loadInfo.setText(R.string.log_in_thread_Connected);
                break;
            case 2:
                loadInfo.setText(R.string.log_in_Thread_Sending_Data);
                break;
            case 3:
                loadInfo.setText(R.string.log_in_thread_Response);
                break;
            case 4:
                loadInfo.setText(R.string.log_in_web_connecting);
                break;
            case 5:
                loadInfo.setText(R.string.log_in_web_connected);
                break;
            case 6:
                loadInfo.setText(R.string.log_in_web_user_data_download);
                break;
            case 7:
                loadInfo.setText(R.string.log_in_web_user_data_downloaded);
                break;
            case 8:
                loadInfo.setText(R.string.log_in_web_device_data_upload);
                break;
        }
    } 

This works if i'm calling it from the AsyncTask from the LogIn Activity but not from the API classes.

I have found a method called .runOnUiThread so I tried to implement that.

private void publishProgress(final int i){
        logInActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                   logInActivity.updateProgress(i);
                Log.d("UI THREAD","HIT");
            }
        });
    }

This is what I have come up with, but it doesn't seem to be hitting, I don't even see the Log post.

I did also have an error implementing this but it was resolved when I added Looper.prepare(); to the Log in AsyncTask

AsyncTask

private class RegistrationWeb extends AsyncTask<Void,Void,Void>{
        private static final String tag = "API_LogIn";
        private String APIKey = null

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            viewFlipper.showNext();
            APIKey = getAPIKey();
        }

        @Override
        protected Void doInBackground(Void... voids) {
            try{
                Looper.prepare();
                GetAPIData get = new GetAPIData();
                URL url = new URL(API_Register_User+APIKey);

                String response = get.GetData(url);

                JSONArray jsonArray = new JSONArray(response);
                JSONObject jsonObject = jsonArray.getJSONObject(0);

                //If the user is accepted
                if(jsonObject.getString("_Code").equals("0")){

                    PublishProgress(8);

                    PostAPIData post = new PostAPIData();
                    url = new URL(API_Register_Device);

                    response = post.PostData(url);

                    jsonArray = new JSONArray(response);
                    jsonObject = jsonArray.getJSONObject(0);

                } else if(jsonObject.getString("_Code").equals("2")){

                }

            } catch (MalformedURLException e) {
                Log.e(tag,e.toString());
            } catch (JSONException e) {
                Log.e(tag,e.toString());
            } catch (IOException e) {
                Log.e(tag,e.toString());
            }
            return null;
        }

        private void PublishProgress(final int i){
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    updateProgress(i);
                }
            });
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
        }
    }
Ali
  • 3,346
  • 4
  • 21
  • 56
Demonic218
  • 893
  • 2
  • 15
  • 33
  • Can you please share your `AsyncTask` code as well? I think there is some problem with the context that you are passing. – Reaz Murshed May 23 '18 at 07:33

1 Answers1

1

You can not directly access string that are present in resource, you will have to to acquire resources first to use its content. You need to call getResources() from your Activity, then you can get the string you are looking for.

YourActivity.context.getResources().getString(R.string.id_name);

Override onProgressUpdate() and then call publishProgress()

    public void publishProgress(Integer v) {
       Message message = new Message();
       message.what = v;
       YourActivity.handler.sendMessage(message);
    }

   @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        publishProgress(values[0);
    }

And change your AsyncTask parameter during its creation from Void to Integer

class RegistrationWeb extends AsyncTask<Integer,Integer,Integer> {

}

In your Activity where your TextView resides on which you want update, make Handler to listen the messages from outer class and in that Handler update your TextView.

Activity:

public static Handler handler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        switch (msg.what) {
            //update your text view on the basis of msg.what
        }
    }
};

Note : Make your TextView loadInfo as static

Ghulam Moinul Quadir
  • 1,638
  • 1
  • 12
  • 17