Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Android Circle Progress Dialog Getting Freezes when Bunch of Data Syncing from Server to Local DB Using Retrofit

1.Iam fetching Bulk of Data from Server and Inserting in the Local Database While Login in android.

2.For Syncing Purpose i have Used Retrofit Library, Syncing and Inserting Working Fine.

My Problem: While Syncing Bunch of Data from server Using Retrofit ,Circle Progress Dialog Getting Freeze.

Help me how to Fix this Issue.

EDIT:1

Called Retrofit method inside Async task ,Still Circle ProgressDialog Getting Freeze

//Calling the Async Task

Asynctask_Getdata task=new Asynctask_Getdata(TokenType_StringValue,Access_Token_StringValue, ID_StringValue);
   task.execute();

//AsyncTask MEthod

public class Asynctask_Getdata extends AsyncTask<String,Void,Void>
    {

        String TokenType_StringValueitem;
        String Access_Token_StringValueitem;
        String ID_StringValueitem;

        public Asynctask_Getdata(String tokenType_StringValueitem, String access_Token_StringValueitem, String ID_StringValueitem) {
            TokenType_StringValueitem = tokenType_StringValueitem;
            Access_Token_StringValueitem = access_Token_StringValueitem;
           ID_StringValueitem = ID_StringValueitem;
        }

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

            if (!pDialog.isShowing())
            {
                pDialog.setIndeterminate(true);
                pDialog.setCanceledOnTouchOutside(false);
                pDialog.setMessage("Please Wait Getting Data...");
                pDialog.show();
            }
        }

        @Override
        protected void onPostExecute(Void aVoid)
        {

            super.onPostExecute(aVoid);
        }

        @Override
        protected Void doInBackground(String... params)
        {
            getLoginDataCall(TokenType_StringValueitem, Access_Token_StringValueitem, ID_StringValueitem );

            return null;
        }
    }


    private void getLoginDataCall(String TokenType_String, String Access_Token_StringValue, String RouteID_String) {

                String Tokenadd = TokenType_String + " Access_Token_StringValue;
                sisClient.getApi().getAllData(Tokenadd, RouteID_String,
                        new Callback<CommonResponse>() {
                            @Override
                            public void success(CommonResponse commonResponse, Response response) {

                                Timber.d("sendOtpAPICall%s", commonResponse.getStatusCode());

                                switch (commonResponse.getStatusCode()) {
                                    case 200:


                                        try {


                                            JSONArray jsonarray = null;
                                            try {
                                                jsonarray = new JSONArray(commonResponse.getRouteMaster());

                                                if (!commonResponse.getRouteMaster().equals("[]")) 
                                                 {
                                                    for (int i = 0; i < jsonarray.length(); i++) 
                                                      {
                                                        JSONObject jsonobject = jsonarray.getJSONObject(i);


                                                        RouteId_StringValue = jsonobject.getString("RouteId");



                                                        Asynxfor_Route_Master_insert(RouteId_StringValue);


                                                    }
                                                } else {
                                                    System.out.println("ROute Master Is NULL ::" + commonResponse.getStatusMessage() + "\n");
                                                }
                                            } catch (Exception e) {
                                                e.printStackTrace();
                                                ;
                                            }

                                      break;

                                    case 404:

                                        pDialog.dismiss();
                                        Toast.makeText(LoginPage.this, R.string.wrong_Username_or_password, Toast.LENGTH_LONG).show();

                                        break;
                                    case 500:
                                        pDialog.dismiss();
                                        Toast.makeText(LoginPage.this, R.string.something_wrong, Toast.LENGTH_LONG).show();
                                        break;

                                }
                            }

                            @Override
                            public void failure(RetrofitError error) {

                                try {
                                    if (error != null) {
                                        pDialog.dismiss();
                                        Timber.i("sendOtpAPICall error %s", error.getResponse().getStatus());
                                        String json = new String(((TypedByteArray) error.getResponse().getBody()).getBytes());
                                        Timber.i("failure  error %s", json.toString());

                                        JSONObject json1 = new JSONObject(json.toString());
                                        String json1string = json1.getString("StatusMessage");


                                        switch (error.getResponse().getStatus()) {
                                            case 404:
                                                Toast.makeText(getApplicationContext(), R.string.wrong_Username_or_password, Toast.LENGTH_LONG).show();
                                                break;
                                            case 500:
                                                Toast.makeText(LoginPage.this, R.string.something_wrong, Toast.LENGTH_LONG).show();
                                                break;
                                            default:
                                                Toast.makeText(LoginPage.this, json1string, Toast.LENGTH_LONG).show();
                                                break;
                                        }


                                    } else {
                                        Timber.i("failure  error %s", "Recieving error null rom server");
                                    }


                                } catch (Exception e) {
                                    e.printStackTrace();
                                    Toast.makeText(LoginPage.this, R.string.something_wrong, Toast.LENGTH_LONG).show();
                                }


                            }

                        });

            }
like image 855
Kumar Avatar asked Aug 01 '16 12:08

Kumar


4 Answers

You can't use pDialog.dismiss();and Toast.makeText in doInBackground.

You must do it in a method, that has access to the UI thread like onProgressUpdate() and onPostExecute().

like image 200
HDehghani Avatar answered Oct 15 '22 14:10

HDehghani


There's no good reason to make a sync Retrofit call in this case, you should use an async call which is provided out of the box from Retrofit. It's very simple, and you can manage your ProgressBar states using the callbacks.

IMO you should not use AsyncTask at all. If you want to explore this check out this, this and this.

Example code conversion from Retrofit v1 sync call with AsyncTask, to Retrofit 2 async call, managed in api class and using Otto event bus for message passing:

public class ApiService {

    private static ApiService INSTANCE;

    // thwart instantiation by protecting
    protected ApiService() {
        // nothing
    }

    public static ApiService getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new ApiService();
        }
        return INSTANCE;
    }

    // -----------------------------------------------------------------------------------

    private static final String BASE_URL = "http://api.service.com/";

    private interface ApiServiceInterface {
        @GET("your/endpoint")
        Call<CommonResponse> postLogin(@Query("token_add") String tokenAdd, @Query("route_id") String RouteId);
    }

    private ApiServiceInterface apiServiceInterface = null;

    private ApiServiceInterface getInterface() {
        if (apiServiceInterface == null) {
            HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
            interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
            OkHttpClient client = new OkHttpClient.Builder()
                    .addInterceptor(interceptor)
                    .build();

            Retrofit retrofit = new Retrofit.Builder()
                    .client(client)
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();

            apiServiceInterface = retrofit.create(ApiServiceInterface.class);
        }
        return apiServiceInterface;
    }

    public void doGetData(Dialog pDialog, String TokenType_String, String Access_Token_StringValue, String RouteID_String) {
        if (!pDialog.isShowing())
        {
            pDialog.setIndeterminate(true);
            pDialog.setCanceledOnTouchOutside(false);
            pDialog.setMessage("Please Wait Getting Data...");
            pDialog.show();
        }
        String Tokenadd = TokenType_String + Access_Token_StringValue;
        getInterface().postLogin(Tokenadd, RouteID_String)
                .enqueue(new Callback<SocketCtrlResponse>() {
            @Override
            public void onResponse(Call<CommonResponse> call, Response<CommonResponse> response) {
                Timber.d("sendOtpAPICall%s", commonResponse.getStatusCode());
                switch (commonResponse.getStatusCode()) {
                    case 200:
                        JSONArray jsonarray = null;
                        try {
                            jsonarray = new JSONArray(commonResponse.getRouteMaster());

                            if (!commonResponse.getRouteMaster().equals("[]")) {
                                for (int i = 0; i < jsonarray.length(); i++) {
                                    JSONObject jsonobject = jsonarray.getJSONObject(i);
                                    RouteId_StringValue = jsonobject.getString("RouteId");
                                    //Asynxfor_Route_Master_insert(RouteId_StringValue);
                                    EventBus.getDefault().post(new GetDataResponseEvent(RouteId_StringValue));
                                }
                            } else {
                                System.out.println("ROute Master Is NULL ::" + commonResponse.getStatusMessage() + "\n");
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                      break;

                    case 404:
                        pDialog.dismiss();
                        Toast.makeText(LoginPage.this, R.string.wrong_Username_or_password, Toast.LENGTH_LONG).show();
                        EventBus.getDefault().post(new GetDataResponseEvent(""));
                        break;

                    case 500:
                        pDialog.dismiss();
                        Toast.makeText(LoginPage.this, R.string.something_wrong, Toast.LENGTH_LONG).show();
                        EventBus.getDefault().post(new GetDataResponseEvent(""));
                        break;
                }
            }

            @Override
            public void onFailure(Call<CommonResponse> call, Throwable t) {
                t.printStackTrace();
                pDialog.dismiss();
                Toast.makeText(LoginPage.this, R.string.something_wrong, Toast.LENGTH_LONG).show();
                EventBus.getDefault().post(new GetDataResponseEvent(""));
            }
        });
    }
}

You'll need an event class to wrap the data you expect to get back from the API, e.g.:

public class GetDataResponseEvent {
    private final String data;

    public GetDataResponseEvent(String data) {
        this.data = data;
    }

    public String getData() {
        return data;
    }
}

And as an example for calling the service from an Activity:

public class YourActivity extends Activity {
    Dialog pDialog;

    // ...

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

        // init pDialog, content view, etc.

        EventBus.getDefault().register(this);

        // ...
    }

    // ...

    public void getDataFromApi() {
        ApiService.getInstance().doGetData(pDialog, TokenType_StringValue,Access_Token_StringValue, ID_StringValue);
    }

    // ...

    public void onEvent(GetDataResponseEvent event) {
        String data = event.getData();
        Asynxfor_Route_Master_insert(data);
    }

    // ...
}

Note again that you'll have to upgrade to Retrofit 2 and use Otto. I've guessed this implementation so it mightn't work as is, but should be a good sketch to get the feel of it.

like image 23
r3flss ExlUtr Avatar answered Oct 15 '22 15:10

r3flss ExlUtr


There are two possible causes of freezing problem.

First: your request operation is running on the UI thread of the application, which is not recommended.

Second: you are trying to test your app on some old device, which has old processor.

I would suggest you using Retrofit's own asynchronous requests, which is described here.The guy who told you that you should not call dialog.dismiss() on the main thread is right. It can freeze your app as well. Here is a good example how to avoid it using method runOnUiThread()

like image 38
RexSplode Avatar answered Oct 15 '22 16:10

RexSplode


This is your RestInteface, where you define the calls to make

interface RestInterface {

    String BASE_URL = "https://you_have_to_specify.com/if_anything/";
    @GET("your_api")
    Call<ModelResponse> getRouteId(@Query String valueItem);
}

This is the implementation class, from where you call

public class RestService {

    private RestInterface restInterface;
    private OkHttpClient okHttpClient;
    public RestService() {

        OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();

        if (BuildConfig.DEBUG) {
            HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
            httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
            clientBuilder.addInterceptor(httpLoggingInterceptor);
        }
        okHttpClient = clientBuilder.build();

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(RestInterface.BASE_URL)
                .client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        restInterface = retrofit.create(RestInterface.class);

    }
    //this is the exposed method
    public void getRoute(String valueId, Callback<ModelResponse> callback){
            Call<ModelResponse> call = restInterface.getRouteId(valueId);
            call.enque(callback);

    }
}

This class should be in the format of your received response

public class ModelResponse{

    String RouteId;

    public String getRouteId(){
        return RouteId; 
    }
}

Now from your activity(or your preferred class), create an object of RestService, and call the method getRoute(), passing your query string and an anonymous callback object(retrofit 2 Callback interface) as parameters. You will get the result in the anonymous callback object as Response. // Added later Your implementation class

public class FromWhereYourApiIsCalled{
    RestService restService = new RestService();
    public void callRouteIdMethod(String value){
      progressDialog.show();// define progress dialog before
      restService.getRoute(value, new Callback<ModelResponse>() {
                @Override
                public void onResponse(Call<ModelResponse> call, Response<ModelResponse> response) {
                    progressDialog.dismiss();
                    Log.v("route Id", response.body().getRouteId());
                }

                @Override
                public void onFailure(Call<ModelResponse> call, Throwable t) {
                    progressDialog.dismiss();
                }
            });
    }
}
like image 35
Debanjan Avatar answered Oct 15 '22 14:10

Debanjan