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();
}
}
});
}
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()
.
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.
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()
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();
}
});
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With