AsyncTask keep returning null - android

I am using for loop to call asynctask
this is how I call the asynctask in a Fragment:
private void LoadPartiList() {
for (int i = 0; i < participants.length; i ++){
String getlistparti = cmd.getPartList();
participants = getlistparti.split(",");
partiparti = ((CommentandLikeActivity)getActivity()).getparticipantlist(participants[i]);
Log.d("test","testlogcat " + partiparti);
}
here my asynctask which allocate in the activity which contain the fragment :
public ArrayList<User> getparticipantlist(final String participationID) {
final ArrayList<User> list = new ArrayList<User>();
final User user = new User();
new AsyncTask<String, String, ArrayList<User>>() {
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected ArrayList<User> doInBackground(String... params) {
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
// Check for success tag
int success;
try {
// Building Parameters
Log.d("participantid", "17112015 " + participationID);
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("userid", participationID));
// getting product details by making HTTP request
// Note that product details url will use GET request
JSONObject json = jsonParser.makeHttpRequest(
"http://192.168.168.111:80/testing/participationlist.php", "GET", params);
// check your log for json response
Log.d("Single Product Details", json.toString());
// json success tag
success = json.getInt("success");
if (success == 1) {
// successfully received product details
JSONArray productObj = json
.getJSONArray("product"); // JSON Array
// get first product object from JSON Array
JSONObject product = productObj.getJSONObject(0);
user.setId(String.valueOf(product.getString(String.valueOf("vuid"))));
user.setUsername(product.getString("vusername"));
user.setProfileimage(product.getString("vprofileimage"));
list.add(user);
Log.d("","getwalalala " +product.getString(String.valueOf("vuid")) +" : "+ product.getString("vusername") + " : " +product.getString("vprofileimage") );
}else{
// product with pid not found
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
return list;
}
#Override
protected void onPostExecute(ArrayList<User> list) {
List<User> mUserlist = new ArrayList<User>();
mAdapterr = new participantlistAdapter(getApplicationContext(), mUserlist);
mAdapterr.Update();
mAdapterr.add(user);
}
}.execute(null, participationID, null);
return list;
}
here is what I Log when run the Asynctask
Logcat for Log.d("","getwalalalala")
but why it will just return [] or null? any wrong with my code? help please...
I want to loop the userid to get username from phpserver according to the length in the participants.length and display in the listview, how should I do it?
I get no answer after research online for few days

As you are trying to return data from AsyncTask which is not correct. AsyncTask doInBackground return data to your onPostExecute. So whatever you are trying to return can only be received in onPostExecute. but still you want to implement Asynctask then you achieve this by one of the following way:
By defining AsyncTask as inner private class in your activity and directly using the data in onPostExecute to update your ui.
Second method is to pass interface callback to your asynctask and with the help of that interface callback update your ui from AsyncTask to activity.

Related

Setting text in EditText causing app crash

I am programming an app in Android Studio. I am taking json file from server, then extracting it to strings and want to show in EditText to let it be modifiable.
Here my code
protected String doInBackground(String... atr) {
new Thread(new Runnable() {
public void run() {
int success;
try {
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("pid", pid));
params.add(new BasicNameValuePair("name", table_name));
JSONObject json = jsonParser.makeHttpRequest(url_product_details, "GET", params);
Log.d("Single Product Details", json.toString());
success = json.getInt(TAG_SUCCESS);
if (success == 1) {
JSONArray productObj = json.getJSONArray(TAG_PRODUCT);
JSONObject product = productObj.getJSONObject(0);
String _name = product.getString("name");
name.setText(_name, EditText.BufferType.EDITABLE);
if(!product.isNull("price")) {
Integer _price = product.getInt("price");
price.setText(_price, EditText.BufferType.EDITABLE);
}
if(!product.isNull("quantity")) {
Integer _quantity = product.getInt("quantity");
quantity.setText(_quantity, EditText.BufferType.EDITABLE);
}
if(!product.isNull("promotion")) {
Integer _promotion = product.getInt("promotion");
promotion.setText(_promotion, EditText.BufferType.EDITABLE);
}
} else {
Intent i = new Intent(getApplicationContext(), AllProductsActivity.class);
i.putExtra(TAG_PID, pid);
i.putExtra("list_name", table_name);
startActivity(i);
finish();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}).start();
return null;
}
unfortunately, when I am trying like this app crashes when i try upload text to EditText. I confirmed that EditText isn't null, Strings too. There is no error message what impede this problem. Have anybody some idea? I looked everywhere (maybe i can't search xD) and didn't find anything reasonable.
First thing, unwrap your code from that Thread. doInBackground() is already asynchronous, so there it's redundant. Either use a Thread or an AsyncTask, not both.
Second thing, Views, such as EditText, can only be modified on the main or UI Thread. When you run setText(), or any other methods on View, it needs to be on the main Thread.
If this is inside an Activity, you can use:
runOnUiThread(new Runnable() {
#Override
public void run() {
//appropriate setText()
}
});
Otherwise, you'll need to use a Handler. Create a global variable:
private Handler handler = new Handler(Looper.getMainLooper());
and instead of using runOnUiThread(), use handler.post(), with the same syntax (just replace runOnUiThread with handler.post).
However, there's also a third thing. You shouldn't really be handling your JSON String in the background. You should only be retrieving the String at that point. Your logic should go in onPostExecute(), which already executes on the main Thread for you.
Your code should look like this:
#Override
protected String doInBackground(String... atr) {
try {
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("pid", pid));
params.add(new BasicNameValuePair("name", table_name));
JSONObject json = jsonParser.makeHttpRequest(url_product_details, "GET", params);
Log.d("Single Product Details", json.toString());
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
return json; //return the JSON String on success
} else {
Intent i = new Intent(getApplicationContext(), AllProductsActivity.class);
i.putExtra(TAG_PID, pid);
i.putExtra("list_name", table_name);
startActivity(i);
finish();
}
} catch (JSONException e) {
e.printStackTrace();
}
return null; //return null for any other result
}
#Override
protected void onPostExecute(String result) {
if (result != null) { //make sure result isn't null
JSONArray productObj = result.getJSONArray(TAG_PRODUCT);
JSONObject product = productObj.getJSONObject(0);
String _name = product.getString("name");
name.setText(_name, EditText.BufferType.EDITABLE);
if (!product.isNull("price")) {
Integer _price = product.getInt("price");
price.setText(_price, EditText.BufferType.EDITABLE);
}
if (!product.isNull("quantity")) {
Integer _quantity = product.getInt("quantity");
quantity.setText(_quantity, EditText.BufferType.EDITABLE);
}
if (!product.isNull("promotion")) {
Integer _promotion = product.getInt("promotion");
promotion.setText(_promotion, EditText.BufferType.EDITABLE);
}
}
}
When you are interacting with any UI element, like EditText, you can't use anything other than UI thread (or main thread).
In other words, UI elements must be changed from UI thread.
What you can do:
Move codes where UI element(like EditText) is updated from doInBackground(String... str) to onPostExecuted(String str).
Every time you use any UI element from another thread, use View.post(Runnable runnable) method. Like:
editText.post(
new Runnable() {
#Override
public void run() {
//do your work
}
}
);
or use Activity.runOnUiThread(Runnable runnable) method when within an Activity
runOnUiThread(
new Runnable() {
#Override
public void run() {
//do your work
}
}
);

While sending Spinner Value to php file first time only its working

I want to pass the Spinner value to php and get some result and display into my TextView. when i use Toast to display the Selected value its working perfect.but while pass the value to the php file i am struck. I tried some ways. can some to fix my problem.
java file:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide(); //<< this for hide title bar
setContentView(R.layout.sales_order);
fg.setOnItemSelectedListener(
new AdapterView.OnItemSelectedListener() {
public void onItemSelected(
AdapterView<?> parent, View view, int position, long id) {
if(goods_name1.getSelectedItem() !=null && goods_name1.getSelectedItem() !=""){
// WebServer Request URL
String serverURL = "http://IP/fs/getProductOneStock.php";
// Use AsyncTask execute Method To Prevent ANR Problem
new LongOperation().execute(serverURL);
}
}
public void onNothingSelected(AdapterView<?> parent) {
showToast("Spinner1: unselected");
}
});
}
// Class with extends AsyncTask class
private class LongOperation extends AsyncTask<String, Void, Void> {
// Required initialization
private final HttpClient Client = new DefaultHttpClient();
private String Content;
private String Error = null;
private ProgressDialog Dialog = new ProgressDialog(Sales_Order.this);
String data ="";
int sizeData = 0;
TextView pro_stock1 = (TextView)findViewById(R.id.tv_stock1);
Spinner fgStock = (Spinner)findViewById(R.id.spinner1);
protected void onPreExecute() {
// NOTE: You can call UI Element here.
//Start Progress Dialog (Message)
Dialog.setMessage("Please wait..");
Dialog.show();
try{
// Set Request parameter
data +="&" + URLEncoder.encode("data", "UTF-8") + "="+fgStock.getSelectedItem();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// Call after onPreExecute method
protected Void doInBackground(String... urls) {
/************ Make Post Call To Web Server ***********/
BufferedReader reader=null;
// Send data
try
{
// Defined URL where to send data
URL url = new URL(urls[0]);
// Send POST data request
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
wr.flush();
// Get the server response
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
// Read Server Response
while((line = reader.readLine()) != null)
{
// Append server response in string
sb.append(line + "");
}
// Append Server Response To Content String
Content = sb.toString();
}
catch(Exception ex)
{
Error = ex.getMessage();
}
finally
{
try
{
reader.close();
}
catch(Exception ex) {}
}
return null;
}
protected void onPostExecute(Void unused) {
// NOTE: You can call UI Element here.
// Close progress dialog
Dialog.dismiss();
if (Error != null) {
pro_stock1.setText("Output : "+Error);
} else {
// Show Response Json On Screen (activity)
pro_stock1.setText( Content );
/****************** Start Parse Response JSON Data *************/
String OutputData = "";
JSONObject jsonResponse;
try {
/****** Creates a new JSONObject with name/value mappings from the JSON string. ********/
jsonResponse = new JSONObject(Content);
/***** Returns the value mapped by name if it exists and is a JSONArray. ***/
/******* Returns null otherwise. *******/
JSONArray jsonMainNode = jsonResponse.optJSONArray("Finish_goods_mas");
/*********** Process each JSON Node ************/
int lengthJsonArr = jsonMainNode.length();
for(int i=0; i < lengthJsonArr; i++)
{
/****** Get Object for each JSON node.***********/
JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
/******* Fetch node values **********/
String Stock1 = jsonChildNode.optString("Finish_goods_mas").toString();
OutputData += Stock1;
}
/****************** End Parse Response JSON Data *************/
//Show Parsed Output on screen (activity)
//jsonParsed.setText( OutputData );
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
my php file
<?php
require "db_config.php";
$Goods_name=$_POST['Goods_name'];
$sql = "select goods_min_level from Finish_goods_mas where Goods_name='".$Goods_name."'";
$stmt = sqlsrv_query( $conn, $sql );
if( $stmt === false) {
die( print_r( sqlsrv_errors(), true) );
}
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) {
//echo $row['cus_id']."<br />";
$json['Finish_goods_mas'][]=$row;
}
sqlsrv_free_stmt( $stmt);
echo json_encode($json);
?>
after make changes of doInBackground and onPreExecute() the Spinner value not pass to php file also i cannot get back result from php
When an asynchronous task is executed, the task goes through 4 steps:
1.onPreExecute(), invoked on the UI thread before the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface.
2.doInBackground(Params...), invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. The parameters of the asynchronous task are passed to this step. The result of the computation must be returned by this step and will be passed back to the last step. This step can also use publishProgress(Progress...) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress...) step.
3.onProgressUpdate(Progress...), invoked on the UI thread after a call to publishProgress(Progress...). The timing of the execution is undefined. This method is used to display any form of progress in the user interface while the background computation is still executing. For instance, it can be used to animate a progress bar or show logs in a text field.
4.onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.
so textView.setText(strOrderNo); do it in onPostExecute(Result) override method

getting arraylist size as ZERO while getting data from server?

I am trying to show data on daynamic list view. I get data from server database. but the problem in my code is task_kist is a string type arraylist. As I execute
new TaskList().execute();
before
Log.i("Total size", String.valueOf(task_list.size()));
this line execute before "new TaskList().execute();" . In class TaskList the size or task_list is 11 but when i check total size as mentioned above, it is 0. Can anyone please suggest me the solution that why size of task_list is zero while I added some values in it.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tasklist);
Bundle bundle = getIntent().getExtras();
username = bundle.getString("username");
Log.i("username from login", username);
registerButtons();
new TaskList().execute();
Log.i("Totalllllll size", String.valueOf(task_list.size()));
String str[] = new String[5];
for(int i =0; i<5;i++) {
str[i]=String.valueOf(task_list.size());
}
ArrayAdapter<String> ap = new ArrayAdapter<String>(this,android.R.layout.test_list_item,str);
lv.setAdapter(ap);
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
Toast.makeText(AllTask.this, "You have Selected : "+((TextView)arg1).getText(), Toast.LENGTH_SHORT).show();
}
});
}
/**
* Background Async Task to Create new product
* */
class TaskList extends AsyncTask<String, String, String> {
/**
* Creating product
* */
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username", username));
// getting JSON Object
// Note that create product url accepts POST method
json = jsonParser.makeHttpRequest(url_get_tasklist,
"GET", params);
// check log cat fro response
Log.i("Create Response", json.toString());
// check for success tag
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
tasks = json.getJSONArray(TAG_NAME);
// looping through All members
for (int i = 0; i < tasks.length(); i++) {
JSONObject c = tasks.getJSONObject(i);
// Storing each json item in variable
tasklist = c.getString(TAG_TASKLIST);
task_list.add(tasklist);
Log.i("size", String.valueOf(task_list.size()));
Log.i("array", task_list.get(i));
}
} else {
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
}
This is because you are getting size in async task which run in background thread.And before completing the async task your log print value as 0
So track log in doInBackground for loop as
// looping through All members
for (int i = 0; i < tasks.length(); i++) {
//your code
}
Log.i("Total size", String.valueOf(task_list.size())); // track log here
Edit
Also you may track log onPostExecute in method as
#Override
protected void onPostExecute(String result) {
Log.i("Total size", String.valueOf(task_list.size())); // track log here
}

implementing the Endless Adapter

I get the entire data from the Server by using doInBackground() method as shown below.
class DataLoader extends Activity{
public void onCreate()
{
...............................
new AsyncTask1().execute();
}
class AsyncTask1 extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(DataLoader.this);
progressDialog.setMessage("Loading...");
progressDialog.setCancelable(false);
progressDialog.show();
}
protected String doInBackground(String... args) {
JSONObject json;
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("param1",datafield1));
params.add(new BasicNameValuePair("param2",datafield2));
json = jsonParser.makeHttpRequest(url, "POST", params);
try {
int success = json.getInt(SUCCESS);
if (success == 1) {
products = json.getJSONArray(PRODUCTS);
// looping through All Products
for (int i = 0; i < products.length(); i++) {
JSONObject c = products.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(ID);
String price = c.getString(PRICE);
String name = c.getString(NAME);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(PID, id);
map.put(PRICE, price);
map.put(NAME, name);
..................
// adding HashList to ArrayList
productsList.add(map);
}
return "success";
}
else {
// no materials found for this section
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String msg) {
if( msg != null && msg.equals("success"))
{
progressDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed JSON data into ListView
* */
customadapter=new CustomAdapterList(DataLoader.this, productsList);
listView.setAdapter(adapter);
}
});
}
}
}
As per the above code, I am setting the data to the listview in the onPostExecute() method only after the entire data is loaded. But now I want to implement the CW Endless Adapter with the present code, but as I am new to this, I am unable to get how to move on from here. I included the CWAdapter jar file in the libs folder. Have referred this and searched a lot , but no use. Can some one please help me implementing the endless feature for the data I get?
Basic Idea is to run an AsyncTask when more data is required, that is when uses scrolls to bottom of the list. Here's a quick demo project.

Using ASync Task to display data in LIstView on postExecute

the problem that im having is kind of weird the printstack of the JSON is correct displaying all the element in the table the way that it should the same as for the method String doInBackground(String... args) the problem is in the postExecute method that is displaying the same element in all the element of the listview "the last element in the row of the table to be exact can someone tell me what i did wrong " thank you for your time bellow you will find the class that im talking about thank you
class LoadAllProducts extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(ProDentActivity.this);
pDialog.setMessage("Loading Balance. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
/**
* getting All products from url
* */
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject json = jParser.getJSONFromUrl(balanceURL, "GET", params);
// Check your log cat for JSON reponse
Log.d("All Products: ", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// products found
// Getting Array of Products
amount = json.getJSONArray(TAG_BALANCE);
// looping through All Products
for (int i = 0; i < amount.length(); i++) {
JSONObject c = amount.getJSONObject(i);
// Storing each json item in variable
String amount = c.getString(TAG_AMOUNT);
String createdat = c.getString(TAG_CREATEDAT);
//String userid = c.getString(TAG_USERID);
// adding each child node to HashMap key => value
map.put(TAG_AMOUNT, amount);
map.put(TAG_CREATEDAT, createdat);
//map.put(TAG_USERID , userid);
// adding HashList to ArrayList
amountlist.add(map);
}
} else {
// no balance found
// Launch Add New balance Activity
Intent i = new Intent(getApplicationContext(),
ProDentActivity.class);
// Closing all previous activities
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
ListAdapter adapter = new SimpleAdapter(
ProDentActivity.this, amountlist,
R.layout.list_item, new String[] { TAG_AMOUNT,TAG_CREATEDAT},
new int[] { R.id.amount, R.id.createdat });
// updating listview
setListAdapter(adapter);
}
});
}
}
JSON:
{"balance":[{"amount":"50000","created_at":"2012-12-15 02:39:13"},{"amount":"50000","created_at":"2012-12-16 15:29:03"},{"amount":"30000","created_at":"2012-12-17 19:38:07"}],"success":1}
...and the method returns
12-18 02:29:05.797: D/All Products:(885): {"success":1,"balance":[{"amount":"50000","created_at":"2012-12-15 02:39:13"},{"amount":"50000","created_at":"2012-12-16 15:29:03"},{"amount":"30000","created_at":"2012-12-17 19:38:07"}]}
problem fixed i found what i have been doing wrong. the problem was that i didn't define my hash map in the method protected String doInBackground(String... args)
i was defining it in the listactivity anw thank you for your time and help
bellow code to be replaced with the old one
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// products found
// Getting Array of Products
amount = json.getJSONArray(TAG_BALANCE);
// looping through All Products
for (int i = 0; i < amount.length(); i++) {
JSONObject c = amount.getJSONObject(i);
// Storing each json item in variable
String amount = c.getString(TAG_AMOUNT);
String createdat = c.getString(TAG_CREATEDAT);
//String userid = c.getString(TAG_USERID);
// adding each child node to HashMap key => value
HashMap<String, String> map = new HashMap<String, String>();
map.put(TAG_AMOUNT, amount);
map.put(TAG_CREATEDAT, createdat);
//map.put(TAG_USERID , userid);
// adding HashList to ArrayList
amountlist.add(map);
}
} else {
// no balance found
// Launch Add New balance Activity
Intent i = new Intent(getApplicationContext(),
ProDentActivity.class);
// Closing all previous activities
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}

Categories

Resources