AsyncTask Android on main thread - android

I'm trying to implement an asynchronous access to internet using AsyncTask, but in log cat PID and TID of my logging are the same, because AsyncTask doesn't create a parallel queue, so my app crashes with a NetworkOnMainThreadException.
Here's my subclass code :
class BL_SimpleAsyncTask extends AsyncTask<Void, Void, Void> {
String requestServer;
HashMap<String, String> postRequestBody;
//------------------------// answer from http client
static DefaultHttpClient sharedClient = null;
boolean isPostRequest;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
System.out.println("bg started");
if (sharedClient == null) {
sharedClient = new DefaultHttpClient();
}
HttpPost post = new HttpPost(requestServer);
String postBody = new String();
postBody += "{";
for (String key : postRequestBody.keySet()) {
String result = String.format("\"%s\":\"%s\",", key, postRequestBody.get(key));
postBody += result;
}
System.out.println("body initialized");
postBody.substring(0, postBody.length() - 1);
postBody += "}";
try {
post.setEntity(new StringEntity(postBody));
} catch (UnsupportedEncodingException e) {
System.out.println(e.getMessage());
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("entity set");
try {
if (post != null) {
System.out.println("starting request....");
HttpResponse response = sharedClient.execute(post);
System.out.println("responce recieved");
} else {
System.out.println("null request");
}
// System.out.println(response) ;
} catch (ClientProtocolException e) {
System.out.println(e.getMessage());
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
System.out.println(e.getMessage());
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
}
}
}
So, to start post-request, I simply do the following :
BL_SimpleAsyncTask obj = new BL_SimpleAsyncTask() ;
obj.requestServer = "https://api.orbios.com/v1/auth/sign-in" ;
obj.postRequestBody = new HashMap<String, String> () ;
obj.postRequestBody.put ("password", password) ;
obj.postRequestBody.put("email", email ) ;
obj.isPostRequest = true ;
System.out.println("start bg thread") ;
obj.doInBackground() ;
What am I doing wrong?

You are not supposed to call doInBackground() yourself. Just call execute() and let the framework call your doInBackground() in a background thread.

Instead of calling directly doInBackground() you should be calling execute method.

Related

Showing ProgressBar on parsing and downloading json result

In my App I am hitting a service which can have no result to n number of results(basically some barcodes). As of now I am using default circular progressbar when json is parsed and result is being saved in local DB(using sqlite). But if the json has large number of data it sometimes takes 30-45 min to parse and simultaneously saving that data in DB, which makes the interface unresponsive for that period of time and that makes user think the app has broken/hanged. For this problem I want to show a progressbar with the percentage stating how much data is parsed and saved so that user get to know the App is still working and not dead. I took help from this link but couldn't find how to achieve. Here's my Asynctask,
class BackGroundTasks extends AsyncTask<String, String, Void> {
private String operation, itemRef;
private ArrayList<Model_BarcodeDetail> changedBarcodeList, barcodeList;
private ArrayList<String> changeRefList;
String page;
public BackGroundTasks(String operation, String itemRef, String page) {
this.operation = operation;
this.itemRef = itemRef;
this.page = page;
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
if (dialog == null) {
dialog = ProgressDialog.show(mActivity, null,
"Please wait ...", true);
}
}
#Override
protected Void doInBackground(String... params) {
// TODO Auto-generated method stub
try{
if (!connection.HaveNetworkConnection()) {
dialog.dismiss();
connection.showToast(screenSize, "No Internet Connection.");
return null;
}
if (operation.equalsIgnoreCase("DownloadChangeItemRef")) {
changeRefList = DownloadChangeItemRef(params[1]);
if (changeRefList != null && !changeRefList.isEmpty()) {
RefList1.addAll(changeRefList);
}
}
if ((changeRefList != null && changeRefList.size() >0)) {
setUpdatedBarcodes(changedBarcodeList);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#SuppressLint("SimpleDateFormat")
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
}
}
ArrayList<String> DownloadChangeItemRef(String api_token) {
ArrayList<String> changedRefList = null;
HttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost(thoth_url + "/" + todaysDate
+ "?&return=json");
String url = thoth_url + "/" + todaysDate + "?&return=json";
String result = "";
try {
changedRefList = new ArrayList<String>();
ResponseHandler<String> responseHandler = new BasicResponseHandler();
result = httpClient.execute(postRequest, responseHandler);
JSONObject jsonObj = new JSONObject(result);
JSONArray jsonarray = jsonObj.getJSONArray("changes");
if (jsonarray.length() == 0) {
return null;
}
for (int i = 0; i < jsonarray.length(); i++) {
JSONObject obj = jsonarray.getJSONObject(i);
changedRefList.add(obj.getString("ref"));
}
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
// when there is no thoth url
Log.i("inclient: ", e.getMessage());
return null;
} catch (Exception e) {
// when there are no itemref
return null;
}
return changedRefList;
}
private boolean setUpdatedBarcodes(
final ArrayList<Model_BarcodeDetail> changedBarcodeList2) {
try {
BarcodeDatabase barcodeDatabase = new BarcodeDatabase(mActivity);
barcodeDatabase.open();
for (Model_BarcodeDetail model : changedBarcodeList2) {
barcodeDatabase.updateEntry(model, userId);
}
n++;
barcodeDatabase.close();
if (RefList1.equals(RefList)) {
if (dialog != null) {
dialog.dismiss();
}
connection.showToast(screenSize, "Barcodes updated successfully");
}
} catch (Exception e) {
Log.i("Exception caught in: ", "setDownloadedBarcodes method");
e.printStackTrace();
return false;
}
return true;
}

How can I access resources of the library

I am trying to create an Android library which provides AsyncTask operations. I created my AsyncTask as below. However, I don't know how to access library's resources. The context field is set by the activity who uses that library. I used to access the resources by calling getActivity().getResources(). But this AsyncTask's context comes from the project that uses it and I don't know how to access the library's resources. How can I achieve that?
public class CheckBalanceAsyncTask extends AsyncTask<Void, Void, Void> {
private Context mContext;
String json;
JSONObject jsonObject,jsonObjResult;
JSONArray jsonArray;
String message,balance;
ProgressDialog progress;
public CheckBalanceAsyncTask (Context context){
mContext = context;
//progress = new ProgressDialog(mContext);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
// progress.setCancelable(false);
// progress.setMessage("please wait");//getString(R.string.pleasewait));
// progress.setTitle("waiting");//getString(R.string.loading));
// progress.setIcon(R.drawable.ic);
// progress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
// progress.setProgress(0);
// progress.setMax(100);
// progress.show();
}
#Override
protected Void doInBackground(Void... params) {
String aliasNo = "";
PackageInfo pinfo = null;
try {
pinfo = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0);
} catch (NameNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
String versionName = pinfo.versionName;
String cardServiceUrl = "blabla";
Log.e("LOGGGGG", cardServiceUrl);
try {
json = JSONParser.getJSONFromUrl(cardServiceUrl);
try {
jsonObject = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser",
"Error creating json object" + e.toString());
}
jsonArray = jsonObject.getJSONArray("cardlist");
jsonObjResult = jsonObject.getJSONObject("result");
message = jsonObjResult.get("message").toString();
Log.e("MESSAGE", "" + message);
JSONObject row = jsonArray.getJSONObject(0);
balance = row.optString("balance");
}
catch (JSONException e) {
Log.e("json", "doInBackground2");
}
return null;
}
#Override
protected void onPostExecute(Void args) {
//progress.dismiss();
try {
if (jsonObjResult.get("message").toString()
.equalsIgnoreCase("ok")) {
Toast.makeText(mContext, balance+" TL", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Ressources are automatically merged with the main application then, no need to do something specific to access string, drawable, layout, etc...
getActivity().getResources() will work fine.

error type mismatch asynctask in android

I'm trying to retrieve data from mysql using asynctask. But I got this
" Type mismatch: cannot convert from AsyncTask
to String"
Though the return from the asynctask process is already string
Here's my codes
public void tampilkanPenyakit() {
try {
String nama = URLEncoder.encode(username, "utf-8");
urltampil += "?" + "&nama=" + nama;
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
xResult = getRequestTampil(urltampil);
try {
parse();
} catch (Exception e) {
e.printStackTrace();
}
}
class ProsesTampil extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... params) {
String sret = "";
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(params[0]);
try{
HttpResponse response = client.execute(request);
sret = EditPenyakit.request(response);
}catch(Exception ex){
}
return sret;
// TODO Auto-generated method stub
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
}
public String getRequestTampil(String UrlTampil){
String sret="";
sret= new ProsesTampil().execute(UrlTampil);
return sret;
}
private void parse() throws Exception {
//jObject = new JSONObject(xResult);
jObject = new JSONObject(xResult);
String sret = "";
JSONArray menuitemArray = jObject.getJSONArray("food");
cb_menu1 = (CheckBox) findViewById(R.id.cb_menu1);
cb_menu2 = (CheckBox) findViewById(R.id.cb_menu2);
cb_menu3 = (CheckBox) findViewById(R.id.cb_menu3);
for (int i = 0; i < menuitemArray.length(); i++) {
sret =menuitemArray.getJSONObject(i).getString(
"penyakit").toString();
System.out.println(sret);
if (sret.equals("1")){
cb_menu1.setChecked(true);
}
else if (sret.equals("2")){
cb_menu2.setChecked(true);
}
}
}
Any help would be appreciated. thanks
The AsyncTask execute() method return the Asyntask itself, you cannot convert it to String.
You need to handle the result in the onPostExecute() method.
Other option could be use the AsynTask get method :
sret= new ProsesTampil().execute(UrlTampil).get();
Take in account the doc:
Waits if necessary for the computation to complete, and then retrieves its result.

onPostExecute not being called by ASyncTask execute()

I can't explain why onPostExecute is not being called in my code. I have successfully used almost this exact code with a different app before. It prints 'onPreExecute' and the successful result of the JSON fetch from doInBackground just before return result; but then onPostExecute doesn't print anything - with the super call or not - and moreover doesn't return my string to the UI thread. Any ideas?
public class PrivateLoadFromServer extends AsyncTask<String, Integer, String> {
InputStream is = null;
String result = null;
String error_text="";
JSONObject j = null;
String url;
SQLiteOpenHelper helper;
CustomActivity activity;
private Context context;
private ProgressDialog dialog;
private int count;
String employee;
String text;
public PrivateLoadFromServer(CustomActivity activity,String employee,String url){
this.url=url;
this.employee=employee;
this.activity=activity;
}
#Override
protected void onPreExecute() {
system.out.println("onPreExecute");
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
System.out.println("onPostExecute");
activity.setJSONResult(result);
/*
if(result!=null){
System.out.println("Task reported successful");
taskHandler.taskSuccessful(this.result);
activity.setJSONResult(this.result);
} else {
taskHandler.taskFailed();
}
*/
//return;
}
#Override
protected String doInBackground(String... params) {
System.out.println("Running aSyncTask");
// Successful code to get JSON result string from server omitted.
System.out.println("Raw at doInBackground: " + result);
return result;
EDIT: Should've posted this originally, I call it as an inner class in CustomActivity like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
helper=new DBHelper(this);
loadBasicData();
}
private void loadBasicData() {
// If you can encode all of these into one JSON Object, cool.
String url="*****" //Omitted URL.
String employee=null;
PrivateLoadFromServer syncTask = new PrivateLoadFromServer(this,employee,url);
syncTask.execute();
try {
syncTask.get(15000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("JSONResult at Activity:"+jsonResult); // jsonResult is null
}
}
public void setJSONResult(String result){
System.out.println("setJSONResult"+result);
this.jsonResult=result; // jsonResult is a field in the Activity.
}
Because you are calling get, the JSON result is also returned from this method (see the source code of AsyncTask.java. So you can call your method directly on the output.
try {
setJSONResult(syncTask.get(15000, TimeUnit.MILLISECONDS));
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
Check if your are explicitly cancelling AsyncTask somewhere in the code before it could postExecute.
onPostExecute() is called on the main UI thread. If its not getting called, it means your UI thread is blocked doing something else.

Android: AsyncTask and reading internet data

I have written a code to download some data from internet. Than i wanted to put it into asyncTask. And after that downloading stopped working. It looks like it cant finish try{} part so skips to exeption.
From main activity "Nekaj" i call loadData() class, which extends AsyncData. From there i call "oto" class inside try command. "oto" class is used to read stuff from internet and returns array of strings. This worked when i called oto class directly from "Nekaj"class. What did I do wrong with using AsyncTask?
Here is the code:
public class Nekaj extends Activity {
TextView Tkolo, Tbroj1;
String[] brojevi_varijabla;
String privremena_varijabla = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.bez_provjere_739);
Tkolo = (TextView) findViewById(R.id.Xkolo);
Tbroj1 = (TextView) findViewById(R.id.Xbroj1);
/*
* try { privremena_varijabla = test.kolo_739();
* Tkolo.setText(privremena_varijabla); } catch (Exception e) { // TODO
* Auto-generated catch block e.printStackTrace(); }
*/
new loadData().execute();
}
public class loadData extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
Oto test = new Oto();
try {
brojevi_varijabla = test.brojevi_739();
if (Integer.valueOf(brojevi_varijabla[0]) > 10) {
Tbroj1.setText("" + brojevi_varijabla[0]);
} else {
Tbroj1.setText(" " + brojevi_varijabla[0]);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
public class Oto {
public String[] brojevi_739() throws Exception {
int i = 0;
int uvjet = 0;
int varijabla = 0;
char[] znak = { '>', '<' };
BufferedReader in = null;
String data[] = null;
String provjera = "date-info";
int[] polje = new int[2];
try {
HttpClient klijent = new DefaultHttpClient();
URI webstranica = new URI(
"https://www.aaa.bb");
HttpGet zahtjev = new HttpGet();
zahtjev.setURI(webstranica);
HttpResponse odgovor = klijent.execute(zahtjev);
in = new BufferedReader(new InputStreamReader(odgovor
.getEntity().getContent()));
StringBuffer brojevi = new StringBuffer("");
String brojevi_string = null;
String neki_string = null;
String red = "";
in.skip(21000);
while ((red = in.readLine()) != null) {
varijabla = red.indexOf(provjera);
if (varijabla != -1) {
// 1. KOLO
if (uvjet == 0) { // onda sadrži taj
// substring
// !!!!
red = in.readLine(); // sada string red sadrži ono
// što
// želim, još moram samo to
// izrezati!!
do {
if (i == 0) {
varijabla = red.indexOf(znak[i]);
}
else {
varijabla = red.indexOf(znak[i], polje[0]);
}
if (varijabla != -1) // ako taj znak postoji u
// stringu
{
if (i == 0) {
polje[i] = varijabla + 1;
}
else {
polje[i] = varijabla;
}
i++;
}
} while (i <= 1);
neki_string = red.substring(polje[0], polje[1]);
Tkolo.setText(neki_string);
provjera = "Dobitna kombinacija";
uvjet++;
continue;
}
}
}
in.close();
brojevi_string = brojevi.toString();
data = brojevi_string.split("\n");
return data;
} finally {
if (in != null) {
try {
in.close();
return data;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}}
What you are doing wrong is Tbroj1.setText() inside the doInBackground() method. What you have to do is to use the onPostExecute method to post your data on the UI:
public class loadData extends AsyncTask<String, Integer, Boolean> {
protected Long doInBackground(String... arg0) {
Oto test = new Oto();
Boolean result = false;
try {
brojevi_varijabla = test.brojevi_739();
result = true;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
protected void onPostExecute(Boolean result) {
if(result){
if (Integer.valueOf(brojevi_varijabla[0]) > 10) {
Tbroj1.setText("" + brojevi_varijabla[0]);
} else {
Tbroj1.setText(" " + brojevi_varijabla[0]);
}
}
}
}
Actually, You are trying to update UI in doInBackGround() of your AsyncTask, so its not allowed (doInBack.. runs in non UI Thread..), So put the UI updation code in onPostExecute() of AsyncTask..
Try this and let me know what happen..
public class loadData extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
Oto test = new Oto();
try {
brojevi_varijabla = test.brojevi_739();
if(brojevi_varijabla != null)
return brojevi_varijabla[0];
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result)
{
if(result != null)
{
if (Integer.valueOf(result) > 10) {
Tbroj1.setText("" + result;
} else {
Tbroj1.setText(" " + result);
}
}
}
}
use onPostExecute(Void result1) {}
to catch the result and perform the action required over there
You can't manipulate UI elements directly on a non-UI (background) thread, which is where doInBackground() always runs. The usual way of using AsyncTask is to get the data in doInBackground(), return it as a value, and then process the UI changes in onPostExecute(). For example:
public class loadData extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... arg0) {
Oto test = new Oto();
try {
brojevi_varijabla = test.brojevi_739();
if (Integer.valueOf(brojevi_varijabla[0]) > 10) {
return "" + brojevi_varijabla[0];
} else {
return " " + brojevi_varijabla[0];
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (result != null) Tbroj1.setText(result);
}
}

Categories

Resources