Runnable error After Asynchtask replacement - android

I am getting an error on the last line below after replacing my asynctask with a runnable to upload data to server: Any pointers will be appreciated.
Cannot return a value from a method with void result type
on this line
return *imageProcessClass.ImageHttpRequest(ServerUploadPath, HashMapParams);
ExecutorService service = Executors.newSingleThreadExecutor ( );
service.execute ( new Runnable ( ) {
#Override
public void run() {
//preexecute
runOnUiThread ( new Runnable ( ) {
#Override
public void run() {
progressDialog = ProgressDialog.show( UploadActivity.this,"Your Data is Uploading To Our Servers",
"Please Wait And Ensure Data is On With Bundles. 3G or WiFi data is preferred",false,false);
}
} );
//doinbackground
ImageProcessClass imageProcessClass = new ImageProcessClass ();
HashMap<String,String> HashMapParams = new HashMap<>();
HashMapParams.put(USER_NAME, userName);
HashMapParams.put(USER_EMAIL, userEmail);
HashMapParams.put(USER_PHONE, userPhone);
HashMapParams.put(ImagePath1, imageView1);
return imageProcessClass.ImageHttpRequest(ServerUploadPath, HashMapParams);

The problem is that run() has no return value where your previous solution with AsyncTask allows a return value.
I expect this return something.
imageProcessClass.ImageHttpRequest(ServerUploadPath, HashMapParams);
but this has void as a return value
#Override
public void run() {
...
}
I think you need a new solution for returning the result, maybe working with a Listener and trigger the callback?
interface ResultListener{
public void onResult(result: ResultType)
}
#Override
public void run() {
...
listener.onResult(imageProcessClass.ImageHttpRequest(ServerUploadPath, HashMapParams);)
}
// Sorry I'm not very familiar with Java anymore, hope you get the idea :)

Related

runonuiThread UI loop

This is my code
I want I show the progressdialog until receive the data from server,
and when I got result from the server(if items.size>0), progressdialog will be dismiss;
But I run this code, I receive the data from the server but in runonuiThread, still running progressdialog.
List<ServerData> items = new ArrayList();
progressdialog.show();
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
HttpRequest...
Gson gson = new Gson();
Type type = new TypeToken<List<ServerData>>(){}.getType();
items = gson.fromJson(String,type);
Log.d("ThreadInfo","" + items.size);
runOnUiThread(new Runnable() {
#Override
public void run() {
if(items.size > 0){
progressdialog.dismiss();
}
}
});
}
});
When I Log the ThreadInfo, It sends items.size value is 1
but still progressdialog is running and not disappear.
Question,
How I can dismiss the progressdialog when items.size is not 0?
If you have any idea, help me please.
You have to change your code like this
if (items.size > 0) {
runOnUiThread(new Runnable() {
#Override
public void run() {
progressdialog.dismiss();
}
});
}

How can use update UI Thread

I have same stock item , I want to send local database to ApiService, But when I send also I want to update ProgressBar message. I tried the code below but it just shows when all proccessing is finishing.
ProgressDialog progress= new ProgressDialog(this);
progress.setTitle(getResources().getString(R.string.progress_exporting));
progress.setMessage("0/0");
when click button I call below method
public void Export() {
runOnUiThread(new Runnable() {
#Override
public void run() {
findViewById(R.id.btnExportOnlineWithStocktaking).setEnabled(false);
progress.show();
}
});
UpdateUI(send, total);
try {
switch (_stocktakingType) {
case Division: {
switch (_onlineExportType) {
case Item: {
isExport = ExportDivisionStocktakingItems(stocktakingId);
}
break;
}
} catch (Exception ex) {
}
}
// ExportDivisionStocktaking method
public boolean ExportCustomStocktakingItems(int stocktakingId) {
result = Boolean.parseBoolean(SendCustomStocktakingItems(stocktakingId,countResults).responseString);
}
My call back method
public ResponseModel SendCustomStocktakingItems(int selectedDivision, List<ExtensionServiceStocktakingItem> countResults) throws ExecutionException, InterruptedException {
return new SendCustomStocktakingItemsService(flag -> true).execute(String.valueOf(selectedDivision), countResults.toString()).get();
}
//AsyncTask method
public class SendDivisionStocktakingItemsService extends AsyncTask<String, Void, ResponseModel> {
public AsyncResponseSendDivisionStocktakingItems delegate = null;
public SendDivisionStocktakingItemsService(AsyncResponseSendDivisionStocktakingItems delegate) {
this.delegate = delegate;
}
#Override
protected ResponseModel doInBackground(String... parameters) {
RequestHandler requestHandler = new RequestHandler();
JSONObject params = new JSONObject();
try {
params.put("stocktakingItems", parameters[1]);
} catch (JSONException e) {
e.printStackTrace();
}
ResponseModel responseModel = requestHandler.getRequestPostString(UHFApplication.getInstance().apiUrl
+ "/api/MobileService/SendDivisionStocktakingItemsPost?stocktakingID="
+ parameters[0],
parameters[1]);
return responseModel;
}
#Override
protected void onPreExecute() {
UpdateUI(send,total);
super.onPreExecute();
}
#Override
protected void onPostExecute(ResponseModel responseModel) {
super.onPostExecute(responseModel);
if (HttpURLConnection.HTTP_OK == responseModel.httpStatus) {
delegate.processFinish(true);
} else {
delegate.processFinish(false);
}
}
}
//UICalled method
public void UpdateUI(int send, int total) {
runOnUiThread(() -> {
progress.setMessage(send + "/" + total);
Log.d("Send Data : ", send + "/" + total);
if (send == total) {
progress.dismiss();
Toast.makeText(getApplicationContext(), "Succsess", Toast.LENGTH_SHORT).show();
}
});
}
//Update
//Ok I have a simle example how can I use. Below code when I click button I wan to open progress firstly and after that for loop is working and update progres message. I try it but not working.
Firstly For loop is working and after that progres opened.
public void ExportTry(){
UpdateUI(send,total);
runOnUiThread(new Runnable() {
#Override
public void run() {
btnExport.setEnabled(false);
progress.show();
}
});
for(int i=0;i<1000000;i++){
UpdateUI(i,1000000);
}
}
You are missing the part of AsyncTask that will allow you to show progress messages while doInBackground is running. Take a look at onProgressUpdate and publishProgress on the same page.
publishProgress
void publishProgress (Progress... values)
This method can be invoked from doInBackground(Params...) to publish updates on the UI thread while the background computation is still running. Each call to this method will trigger the execution of onProgressUpdate(Progress...) on the UI thread. onProgressUpdate(Progress...) will not be called if the task has been canceled.

Freezing app when using AsyncTask

I download a high amount of data from API and want to make it efficient so I get first 100 record in one asyncTask and then in another asyncTask get another several thousands(in 500 hundred portions) The loadListAsynchronously(); looks identicall as loadData function without content,progress,loadContent(); function but this functions are not the problem - without loadListAsynchronously(); app runs smoothly after frezee when download first data. I tried add transaction but that does not help me.
private void loadData() {
DottedProgressBar progressBar = (DottedProgressBar) findViewById(R.id.loadIngDots);
progressBar.startProgress();
content = (LinearLayout)findViewById(R.id.activity_main) ;
progress = (RelativeLayout) findViewById(R.id.progressPage) ;
AsyncTask<String, Void, String> read =new AsyncTask<String, Void, String>() {
SharedPreferences keyValues;
#Override
protected void onPreExecute() {
content.setVisibility(View.GONE);
keyValues = getSharedPreferences(Settings.MODEL_LAST_CALL, Context.MODE_PRIVATE);
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
height = displaymetrics.heightPixels;
width = displaymetrics.widthPixels;
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
modelList = new ArrayList<>();
Map<String,String> options= new HashMap<>();
options.put("limit",String.valueOf(AMOUNT_OF_LOADED_modelS));
ApiHelper.getModelWithParams(new Callback<ModelApiEnvelope>() {
#Override
public void onResponse(Call<ModelApiEnvelope> call, Response<ModelApiEnvelope> response) {
Log.i(TAG,"First call model Get response");
final ModelApiEnvelope envelope = response.body();
if(envelope==null)
Toast.makeText(MainActivity.this,getString(R.string.server_down_explanation),Toast.LENGTH_SHORT).show();
else{
try {
final Dao<Model,Integer> modelDAO = getHelper().getmodelDAO();
final Dao<Submodel,Integer> submodelDAO=getHelper().getsubmodelDAO();
TransactionManager.callInTransaction(getHelper().getConnectionSource(),
new Callable<Void>() {
public Void call() throws Exception {
modelList=envelope.getData();
Log.i(TAG,"LoadData loop Start");
for( final model m: modelList){
m.setLogo(m.getLogo()+"?width="+width/2+"&height="+height);
m.setLanguage(m.getLanguage().substring(0,2));
if(m.getLanguage().equals("uk"))
m.setLanguage("ua");
if(m.getsubmodels().size()!=0){
for(final submodel e: m.getsubmodels()){
e.setLanguage(m.getLanguage());
submodelDAO.createOrUpdate(e);
}
}
try {
modelDAO.createOrUpdate(m);
}catch (SQLException e) {e.printStackTrace();}
}
return null;}
});
if(envelope.getData().isEmpty()){
SharedPreferences.Editor editor = sharedPreferences.edit();
long time = System.currentTimeMillis();
editor.putString(Settings.model_LAST_CALL , Long.toString(time));
editor.apply();
}
else
loadListAsynchronously();
} catch (SQLException e) {
Log.i(TAG," message "+e.getMessage()) ; e.printStackTrace();
}}
loadContent();
content.setVisibility(View.VISIBLE);
progress.setVisibility(View.GONE);
}
#Override
public void onFailure(Call<modelApiEnvelope> call, Throwable t) {
Log.i(TAG,"ERROR"+ t.getMessage());
Toast.makeText(MainActivity.this,getString(R.string.server_down_explanation),Toast.LENGTH_LONG).show();
loadContent();
}
},MainActivity.this,options, keyValues.getString(lang,"0"));
return null;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
};
read.execute();
}
UPDATE: Method Trace added
UPDATE 2: Removing the transaction solve my problem. It seems that the making transaction for thousands saveings into database freeze Ui.
Callback in Retrofit1 and AsyncTask are not compatible. You have to modify your API interface from something like this :
public interface Api {
void getModelWithParams(Callback<Something> callback);
}
To this :
public interface Api {
Something getModelWithParams();
}
Then Retrofit will not provide async execution support and you can execute that row method inside AsyncTask.doInBackground method.
Other option is to stay with that interface definition and just call Retrofit method directly (without AsyncTask wrapping). The question is if your further logic is not heavy, because onResponse will be executed on UI Thread which cause your freezes and in general is root cause of your problem.

Android - How to accommodate a thread executing in AsyncTask doInBackground method

I am trying to query a web service using loopJ and during this operation I want to show the users a progress dialog. When the operation is complete, I want the progress dialog to dismiss and start a new activity intent.
I know AsyncTask is the way to go. On onPreExecute method I show the progress dialog. On doInBackground I am performing the network operation. And onPostExecute I am dismissing the dialog and starting a new activity intent.
My issue is doInBackground will perform loopJ networkcall asynchronously so onPostExecute will finish first before my network operation. If you look at my logs it will show:
"Starting new activity!"
"Fetched category services!"
rather
"Fetched category services!"
"Starting new activity!"
How do I accommodate an asynchronous task running doInBackground? Is there a way in onPostExecute to wait till my asynch loopJ operation is done?
public class FetchCategoriesServices extends AsyncTask<HITECategory, String, String>
{
private Category userSelectedCategory;
private ProgressDialog busyDialog;
#Override
protected void onPreExecute()
{
busyDialog = ProgressDialog.show(SearchActivity.this, getApplicationContext().getString(R.string.progressDialogTitle),
getApplicationContext().getString(R.string.progressDialogMessage));
}
#Override
protected String doInBackground(HITECategory... params)
{
userSelectedCategory = params[0];
String requestCategoryServiceURL = BASE_URL + "GetServices?CategoryID=" + userSelectedCategory.categoryID + "&ResponseType=JSON";
try
{
Client.get(requestCategoryServiceURL, new AsyncHttpResponseHandler()
{
#Override
public void onSuccess(String jsonResponse)
{
Gson gson = new Gson();
CategoryServicesListResponse Response = gson.fromJson(jsonResponse, CategoryServicesListResponse.class);
categoryServiceresults = Response.categoryServices;
Log.d(getString(R.string.DebugKey), "Fetched category services!");
}
});
}
catch (Exception e)
{
Log.d(getString(R.string.DebugKey), "Error connecting to service and fetching category services list");
}
return null;
}
#Override
protected void onPostExecute(String params)
{
busyDialog.dismiss();
Log.d(getString(R.string.DebugKey), "Starting new activity!");
Intent intent = new Intent(getApplicationContext(), CategoriesSearchActivity.class);
startActivity(intent);
}
}
Just put the code in onPostExecute into onSuccess method:
Client.get(requestCategoryServiceURL, new AsyncHttpResponseHandler()
{
#Override
public void onSuccess(String jsonResponse)
{
Gson gson = new Gson();
CategoryServicesListResponse Response = gson.fromJson(jsonResponse, CategoryServicesListResponse.class);
categoryServiceresults = Response.categoryServices;
Log.d(getString(R.string.DebugKey), "Fetched category services!");
youractivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
busyDialog.dismiss();
Log.d(getString(R.string.DebugKey),
"Starting new activity!");
Intent intent = new Intent(getApplicationContext(),
CategoriesSearchActivity.class);
youractivity.this.startActivity(intent);
}
});
}
});

StrictModeDiskReadViolation only gets resolved with AsyncTask, why?

I am using strict mode for android 3.2 and am getting StrictModeDiskReadViolation during onCreate in my Activity.
I tried to moved the code that does an SQL query to:
a new Thread.
a new AsyncTaskLoader.
a new AsynTask.
The problem is only AsyncTask made the Violation dissappear and I'm wondering why the other two methods didn't work?
Here is my code:
AsyncTask<Void, Void, Void> asyncTask = new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
try {
Dao<Listino, Integer> dao = DatabaseHelper.getHelper(ListinoActivity.this).getListinoDao();
if (dao.countOf() == 1)
{
long id = dao.queryForAll().get(0).getId();//long non int
final Intent intent = new Intent(ListinoActivity.this, ListinoProdottiActivity.class);
intent.putExtra("listino_id", id);
intent.setAction(Intent.ACTION_MAIN);
ListinoActivity.this.finish();
ListinoActivity.this.startActivity(intent);
}
} catch (SQLException e) {
runOnUiThread(new Runnable() {
#Override
public void run() {
MyToast.makeText(ListinoActivity.this, "Errore ottenere i listini", MyToast.LENGTH_SHORT).show();
}
});
e.printStackTrace();
}
return null;
}
};
asyncTask.execute();
AsyncTaskLoader async = new AsyncTaskLoader(this) {
#Override
public Object loadInBackground() {
//do stuff, violation still here
return null;
}
};
async.loadInBackground();
Thread t = new Thread() {
#Override
public void run() {
super.run();
//do stuff, violation still here
}
};
t.run();
You did not fork a Thread. To fork a Thread, you call start(). You called run(), which simply ran your run() method on the current thread.
And you did not come even close to using the Loader framework properly. The code you have there not only suffers from the same flaw as what you did with your Thread, but that is not how you use a Loader.

Categories

Resources