Networking with Volley - java

Please could you help me with a network request I am trying here.
I have 2 Classes Network.class and MainActivity.class. I have a TextView in the MainActivity Class that I would like to be replaced with the text I get from the Network call in the Network Class. Problem I am currently having is I cant initiate the network call in the Network Class when the MainActivity Class is loaded when the application starts?
Below is the Code to MainActivity:
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView)findViewById(R.id.text);
String test = Network.userName;
tv.setText(test);
}
}
and below is the network class that I would like to do the network call and the response will need to replace the text in the TextView in the MainActivity Class.
Network Class:
public class Network extends Activity{
public static String userName;
private String jsonResponse;
String url_home = "http://www.someurl.com";
private void postData(final TextView tv) {
final RequestQueue request = Volley.newRequestQueue(this);
JsonObjectRequest postReq = new JsonObjectRequest(Request.Method.GET, url_home, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
jsonResponse = "";
for(int i = 0; i< response.length(); i++) {
String userName = response.getString("DOTWBannerHD");
System.out.println("++++++++++++++++++++++++++++++++++++++++++++userName = " + userName);
jsonResponse += userName;
System.out.println("++++++++++++++++++++++++++++++++++++++++++++JsonResponse = " + jsonResponse);
}
tv.setText(jsonResponse);
} catch (JSONException e){
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println("Error [" + error + "]");
}
}) {
#Override
public Map getHeaders() throws AuthFailureError {
Map headers = new HashMap();
headers.put("Accept", "application/json");
System.out.println(headers);
return headers;
}
};
request.add(postReq);
}
}
I am very new to Android and am battling to call the postData method from the second activity, in the MainActivity? The issue I get is that the TextView has text hard coded in the XML but when I run the Application it is blank? It's like, either the response is blank, but I doubt its that because the code I put in the Network Class (System.out.println("++++++++++++++++++++++++++++++++++++++++++++userName = " + userName);) isn't showing up in the Terminal which makes me think that its not running the postData method at all or the response is not working but it just sets the TextView to blank?

You cannot change the GUI from an async-task.
As JsonObjectRequest works asynchronous you should run tv.setText(jsonResponse); on the main thread using:
runOnUiThread(new Runnable() {
public void run() {
tv.setText(jsonResponse);
}
});

Following up on my comment, the reason your are not seeing anything in the terminal is because you're not calling you postData method so it's never executed.
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView)findViewById(R.id.text);
Network network = new Network();
network.postData(tv);
}
}
and make Network a normal class not an Activity.
public class Network{
////The variables and your postData method here
}

Related

No content displays when app runs on recyclerViewPager

This is the code I am Using.
public class MainActivity extends AppCompatActivity {
public ArrayList<String> ImageUrls = new ArrayList<>();
public ArrayList<String> ImageNames = new ArrayList<>();
public ArrayList<String> ImageDesc = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initImages();
}
private void initImages(){
final OkHttpClient client = new OkHttpClient();
final Request request = new Request.Builder()
.url("http://url.in/wp-json/wp/v2/posts?_embed")
.build();
#SuppressLint("StaticFieldLeak") AsyncTask<Void, Void, String> asyncTask = new AsyncTask<Void, Void, String>() {
private static final String TAG = "SlideFragment";
#Override
protected String doInBackground(Void... params) {
try {
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) {
Log.d(TAG, "doInBackground: REsponse Un Successfull - 56");
return null;
}
String Data = response.body().string();
response.body().close();
return Data;
} catch (Exception e) {
e.printStackTrace();
Log.d(TAG, "doInBackground: Exceptione on line63");
return null;
}
}
#Override
protected void onPostExecute(String Data) {
super.onPostExecute(Data);
if (Data != null) {
Log.d(TAG, "onPostExecute: line72");
try {
JSONArray json = new JSONArray(Data);
for (int i = 0; i < json.length(); i++) {
JSONObject post = json.getJSONObject(i);
String title = post.getJSONObject("title").getString("rendered");
String description = post.getJSONObject("content").getString("rendered");
String imgURL = post.getJSONObject("_embedded").getJSONArray("wp:featuredmedia").getJSONObject(0).getJSONObject("media_details").getString("file");
String imagUrl = "http://url.in/wp-content/uploads/" + imgURL;
ImageNames.add(title);
ImageDesc.add(description);
ImageUrls.add(imagUrl);
Log.d(TAG, "onPostExecute: " + ImageNames);
}
}catch(JSONException j){
j.printStackTrace();
Log.d(TAG, "onPostExecute: on line 121");
}
}
}
};
asyncTask.execute();
initRecycler();
}
private void initRecycler(){
RecyclerViewPager mRecyclerView = (RecyclerViewPager) findViewById(R.id.list);
// setLayoutManager like normal RecyclerView, you do not need to change any thing.
LinearLayoutManager layout = new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false);
mRecyclerView.setLayoutManager(layout);
//set adapter
//You just need to implement ViewPageAdapter by yourself like a normal RecyclerView.Adpater.
RecyclerViewAdapter adapter = new RecyclerViewAdapter(ImageUrls, ImageNames, ImageDesc, this);
mRecyclerView.setAdapter(adapter);
}
}
I have run the same code with local data i..e the ArrayList with hardcoded data. It works. But If I try with API data It shows Nothing. I have checked the ArrayList with logging. It is fine.
I don't know where I am Wrong.
UPDATE
Thanks to #sonhnLab. In the code I have removed initRecycler(); from initImages(); and added to onPostExecute();. That worked.
Due to the asynchronous nature of Asynctask, the following line: "initRecycler();" doesn't necessarily gets called after completion of the network request hence no content. Remember, any task that depends on the asynchronous response needs to be implemented inside response method, in this case inside onPostExecute().
With the Help of sonhnlab I have successfully got the desired output.
I have made this initRecycler(); call into onPostExecute() call. so when the information is ready from the API call it initiates the Recycler.
I have Updating the Code in the question.
You should call initRecyler() onPostExecute when async task is completed

doInBackground not updating variable

I'm working on a basic android app that makes a POST with HttpURLConnection. I want to return the response Message from my Web API.
My MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView mTextView = findViewById(R.id.textView);
AsyncExample asyncExample = new AsyncExample();
asyncExample.execute();
mTextView.setText(asyncExample.getResponseMsg());
}
}
My AsyncExample.java
class AsyncExample extends AsyncTask<Void, Void, Void> {
private HttpURLConnection con;
private String responseMsg;
protected void onPreExecute() {
responseMsg = "empty message";
}
#Override
protected Void doInBackground(Void... params) {
String urlParameters = "param1=data1";
byte[] postData = urlParameters.getBytes(Charset.forName("UTF-8"));
int postDataLength = postData.length;
String request = "http://192.168.1.30:6262";
URL url = null;
try {
url = new URL(request);
con = (HttpURLConnection) url.openConnection();
con.setDoOutput(true);
con.setInstanceFollowRedirects(false);
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
con.setRequestProperty("charset", "utf-8");
con.setRequestProperty("Content-Length", Integer.toString(postDataLength));
responseMsg = con.getResponseMessage();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public String getResponseMsg() {
return responseMsg;
}
}
After running the app, i get empty message in my TextView. Why it is not getting updated my doInBackground? Even if con.getResponseMessage() is null, it should be updated?
The problem is that your AsyncTask is executed asynchronously, while you try to retrieve the value immediately. You need to implement this a little bit differently. Either leverage the API of AsyncTask, sine it posts callbacks for your on the UI thread. You can update your TextView directly in your AsyncTask
class MyAwesomeAsyncTask extends AsyncTask<Void, Void, String> {
#Override
protected void onPreExecute() {
myTextView.setText("progress started");
}
#Override
protected String doInBackground(final Void... voids) {
String s = amazingCallToBackend();
return s;
}
#Override
protected void onPostExecute(final String s) {
myTextView.setText(s);
}
}
Or if you just want the value, you can pass a Callback to your async task that will deliver the value to you, something like that
interface Callback {
void onValueReceived(String value);
void onFailure();
}
class MyAwesomeAsyncTask extends AsyncTask<Void, Void, String> {
private Callback callback;
MyAwesomeAsyncTask(final Callback callback) {
this.callback = callback;
}
#Override
protected String doInBackground(final Void... voids) {
String s = amazingCallToBackend();
return s;
}
#Override
protected void onPostExecute(final String s) {
callback.onValueReceived(s);
}
}
Here's how you create it
Callback callback = new Callback() {
#Override
public void onValueReceived(final String value) {
}
#Override
public void onFailure() {
}
};
new MyAwesomeAsyncTask(callback).execute();
However, be careful because if for some reason your activity/fragment is gone/finished before your AsyncTask is done, this can cause memory leaks.
A quick Google search will tell you all you want about AsyncTask leaking memory :)
Your doInBackground method take time to execute. you are immediately calling mTextView.setText(asyncExample.getResponseMsg()); but asynctask has been not been finished yet. You need to wait until your doInBackground finish and then call that setText you can do it in onPostExecute method.
AsyncTask has 3 default method
1. On preexecute
2. Do in background
3. On post execute
post execute:
The response got from the doinbackground is in the post execute.
Here we can process the result . use the runnable method to update text view ui
Override the onPostExecute() Method to return the text. In the Main Activity create a method to update the TextView after completing the execution of the Async Task. It is coming blank as because the Main Thread is not paused its executing and setting the text View but the Async task has not yet finished executing and hence the String is empty. So wait for the Async Task to finish before setting the text view.
String str_result= new RunInBackGround().execute().get();
Refer to this for more information.
You can do it in a number of ways. I'd try to suggest you a way that would require negligible amount of changes to your existing code.
Declare the mTextView as a Global variable, Override onPostExecute() method inside your AsyncExample and update mTextView inside that onPostExecute() method with the value passed to it by the doInBackground() method [here, notice that responseMsg is returned at the end of doInBackground() ground which is caught as a String value (result) by the onPostExecute() method]. However, I also think that its a good idea to Override your onPreExecute() method.
In order to do so, your MainActivity.java should be as follows:
public class MainActivity extends AppCompatActivity {
TextView mTextView; //declare mTextView outside the onCreate() method as a Global String variable.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = findViewById(R.id.textView);
AsyncExample asyncExample = new AsyncExample();
asyncExample.execute();
}
}
Please make your asynctask an inner-class of the same activity and edit it as follows:
class AsyncExample extends AsyncTask<Void, Void, Void> {
private HttpURLConnection con;
private String responseMsg;
#Override // Its a good practice to Override the onPreExecute() method.
protected void onPreExecute() {
responseMsg = "empty message";
}
#Override
protected String doInBackground(String... params) {
String urlParameters = "param1=data1";
byte[] postData = urlParameters.getBytes(Charset.forName("UTF-8"));
int postDataLength = postData.length;
String request = "http://192.168.1.30:6262";
URL url = null;
try {
url = new URL(request);
con = (HttpURLConnection) url.openConnection();
con.setDoOutput(true);
con.setInstanceFollowRedirects(false);
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
con.setRequestProperty("charset", "utf-8");
con.setRequestProperty("Content-Length", Integer.toString(postDataLength));
responseMsg = con.getResponseMessage();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return responseMsg; //return the value of responseMsg
}
#Override //override onPostExecute() method
protected void onPostExecute(String result) { //receive the value to be set to mTextView which is returned by the doInBackground() method.
mTextView.setText(result);
}
}
Try to do like this
MainActivity
public class MainActivity extends AppCompatActivity {
TextView mTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = findViewById(R.id.textView);
AsyncExample asyncExample = new AsyncExample(this,mTextView);
asyncExample.execute();
}
}
AsyncTask
class AsyncExample extends AsyncTask<Void, Void, Void> {
private HttpURLConnection con;
private String responseMsg;
private MainActivity mContext;
TextView mTextView;
public AsyncExample (MainActivity context, TextView textView) {
mContext = context;
mTextView = textView;
}
protected void onPreExecute() {
responseMsg = "empty message";
}
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
protected Void doInBackground(Void... params) {
String urlParameters = "param1=data1";
byte[] postData = urlParameters.getBytes(StandardCharsets.UTF_8);
int postDataLength = postData.length;
String request = "http://192.168.1.30:6262";
URL url = null;
try {
url = new URL(request);
con = (HttpURLConnection) url.openConnection();
con.setDoOutput(true);
con.setInstanceFollowRedirects(false);
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
con.setRequestProperty("charset", "utf-8");
con.setRequestProperty("Content-Length", Integer.toString(postDataLength));
responseMsg = con.getResponseMessage();
mContext.runOnUiThread(new Runnable() {
#Override
public void run() {
mTextView.setText(responseMsg);
}
});
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public String getResponseMsg() {
return responseMsg;
}
}

Android - Send HTTP Request with AsyncTask on Button Click | Problems with delegate

i am about to write a small application. On button click i send a http request in a custom async task class. I want to write this value in a EditText field and in a ListView as item. My problem now is that i want to return the value of the request to the main thread to process it further. I searched around and found a method with an interface. This is my asynctask class:
public class Request extends AsyncTask<String,Void,String> {
public AsyncResponse delegate=null;
private MainActivity mAct;
public Request(MainActivity mainActivity){
this.mAct = mainActivity;
}
#Override
protected String doInBackground(String... url){
String returnString = "";
try {
URL u = new URL(url[0]);
final HttpURLConnection connection = (HttpURLConnection)u.openConnection();
BufferedInputStream bis = new BufferedInputStream(connection.getInputStream());
byte[] content = new byte[1024];
int bytesRead = 0;
String strContent = "";
while((bytesRead = bis.read(content)) != -1){
strContent += new String(content,0,bytesRead);
}
returnString = strContent;
} catch (Exception e){
} finally {
return returnString;
}
}
protected void onPostExecute(String result){
delegate.processFinish(result);
}
}
And this is my MainActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button btnSend = (Button)findViewById(R.id.btnSendMessage);
final ListView lv = (ListView)findViewById(R.id.treeView);
final EditText editText = (EditText)findViewById(R.id.txtReqID);
final MainActivity ma = this;
final ArrayList<String> arrList = new ArrayList<String>();
final ArrayAdapter<String> arrAdapter = new ArrayAdapter<String>(getApplicationContext(),R.layout.simple_list_item_1,arrList);
btnSend.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
String t = new String("http://myhttprequest");
Request r = new Request(ma);
public void onCreate(Bundle savedInstanceState){
r.delegate = this;
}
editText.setText(returnValue);
lv.setAdapter(arrAdapter);
arrList.add(returnValue);
arrAdapter.notifyDataSetChanged();
}
});
}
public interface AsyncResponse{
void processFinish(String output);
}
The problem is that i have to declare every variable as final because i acces them within a function. I don't feel very happy with my code now and i also have no idea how i can make this work. Any help is very much appreciated.
Best regards
Try this way:
btnSend.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
String t = new String("http://myhttprequest");
Request r = new Request(ma){
protected void onPostExecute(String result){
editText.setText(result);
lv.setAdapter(result);
arrList.add(result);
arrAdapter.result();
}
};
}
});
What you should do I pretty simple.
Create an AsyncTask constructor that takes "delegate" as param
1.1 In case the "delegate" is an Activity (it is in your case) just make sure it's hold in a WeakReference (to avoid memory leaks)
Do you thing with http
When you want to dispatch the callback, just use your "delegate" param (check for null - as it is a WeakReference).
Cheers!

Displaying a String of a java class in an activity widget

I have an android app that consist of an activity and a java class that extends AsyncTask. So I have a String in the java class that called resFromServer
which I want to display it in a message in a suitable android widget like Alertdialog .
I want someone to help me in how to access that String from the activity
public class JSONTransmitter extends AsyncTask<JSONObject, JSONObject, JSONObject> {
String url = "http://192.168.1.8:89/Derdeery/b.php";
protected JSONObject doInBackground(JSONObject... data) {
JSONObject json = data[0];
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 100000);
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitNetwork().build());
JSONObject jsonResponse = null;
HttpPost post = new HttpPost(url);
try {
StringEntity se = new StringEntity("json="+json.toString());
post.addHeader("content-type", "application/x-www-form-urlencoded");
post.setEntity(se);
HttpResponse response;
response = client.execute(post);
String resFromServer = org.apache.http.util.EntityUtils.toString(response.getEntity());
Log.i("Response from server", **resFromServer**);
}
catch (Exception e)
{ e.printStackTrace();}
return jsonResponse;
}
}
the activity
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
} }
Proper solution: create an instance of the AsyncTask and make a callback in order to catch the response into any Activity. All Activities which will implement this interface, can retrieve the result of the AsyncTask. This is more flexible and can be used by multiple Activities with just one single AsyncTask.
You have to create the instance and return the String response, in AsyncTask:
public class JSONTransmitter extends AsyncTask<JSONObject, Void, String> {
private AsyncCallback asyncCallback; // callback variable
// constructor
public JSONTransmitter(Context context) {
// attach the callback to any context
asyncCallback = (AsyncCallback) context;
}
// create the interface
public static interface AsyncCallback {
void onResponse(String res);
}
...
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (asyncCallback != null) {
// call the onResponse method for callback
asyncCallback.onResponse(result);
}
}
}
Then, you can implement to any Activity the callback by setting its Context as follows:
public class MainActivity extends Activity implements JSONTransmitter.AsyncCallback {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// set the Context to the AsyncTask when you create it
// in order to return here and execute the request
new JSONTransmitter(this).execute(...);
}
...
#Override
public void onResponse(String res) {
// handle the string response when it's called from onPostExecute()
Log.v("From_MainActivity", "AsyncTask returns this: "+res);
}
}
Therefore, you can do what you want in the Activity with resFromServer (result string) from AsyncTask class.
Pass your activity as parameter to your AsyncTask class constructor :
class MyAsyncTask extends AsyncTask<URL, Integer, Long> {
Activity mActivity;
public MyAsyncTask(Activity activity) {
mActivity = ativity;
}
Then update your activity:
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
int id = mActivity.findViewById(...);
}
You should not use the doInBackground method to update the activity.
Use the onPostExecute because it uses the main Thread.

onPostExecute retrieves null from server

I trying read data from server by using AsyncTask, but when i give the parameter to onPostExecute, it retrieves me null.The MainActivity class:
public class MainActivity extends Activity{
EditText name, password;
Button login;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
name = (EditText) findViewById(R.id.name);
password = (EditText) findViewById(R.id.password);
login = (Button) findViewById(R.id.login);
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
TextView uiUpdate = (TextView) findViewById(R.id.output);
String outputasync = uiUpdate.getText().toString();
String serverURL = "http://192.168.1.105/myapp/text.php";
LongOperation longOperation = new LongOperation(MainActivity.this);
longOperation.execute(serverURL);
longOperation.onPostExecute(uiUpdate);
}
});
}
The AsyncTask:
public class LongOperation extends AsyncTask<String, Void, String> {
private Context mcontext;
private String content;
private String error = null;
AlertDialog alertDialog;
public LongOperation(Context context){
mcontext = context ;
}
#Override
protected void onPreExecute() {
alertDialog = new AlertDialog.Builder(mcontext).create();
alertDialog.setTitle("Login Information....");
}
#Override
protected String doInBackground(String... urls) {
try {
URL url = new URL(urls[0]);
HttpURLConnection client = (HttpURLConnection)url.openConnection();
client.connect();
InputStream inputStream = client.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
content = bufferedReader.readLine();
bufferedReader.close();
inputStream.close();
client.disconnect();
} catch (IOException e) {
error = e.getMessage();
}
return null;
}
protected void onPostExecute(TextView unused) {
alertDialog.dismiss();
if (error != null) {
unused.setText("Output : " + error);
} else {
unused.setText("Output : "+ content);
}
}
}
The connectivity to server is correct, the problem is display the message inside the server in the TextView.
Upadte and solution
Like androholic said :
You should not be calling onPostExecute manually from your code. Calling execute on the asynctask should suffice. onPostExecute will automatically be called when the asynctask finishes its work.
And change the onPostExecute parameter to String
And for retrieve a TextView with the message of the server, i did what Sharj said:
2) How to set your TextView that is in your Activity. The simplest way is to pass activity variable to LongOperation constructor and use that for accessing TextView in onPostExecute.
The AsyncTask:
public class LongOperation extends AsyncTask<String, Void, String> {
TextView textviews;
private Context mcontext;
private String content;
private String error = null;
AlertDialog alertDialog;
public LongOperation(Context context, TextView textView){
textviews = textView;
mcontext = context ;
}
#Override
protected void onPreExecute() {
alertDialog = new AlertDialog.Builder(mcontext).create();
alertDialog.setTitle("Login Information....");
}
#Override
protected String doInBackground(String... urls) {
try {
URL url = new URL(urls[0]);
HttpURLConnection client = (HttpURLConnection)url.openConnection();
client.connect();
InputStream inputStream = client.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
content = bufferedReader.readLine();
bufferedReader.close();
inputStream.close();
client.disconnect();
} catch (IOException e) {
error = e.getMessage();
}
return null;
}
#Override
protected void onPostExecute(String unused) {
alertDialog.dismiss();
if (error != null) {
unused=("Output : " + error);
textviews.setText(unused);
} else {
unused=("Output : "+ content);
textviews.setText(unused);
}
}
The MainActivity class:
public class MainActivity extends Activity{
EditText name, password;
Button login;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
name = (EditText) findViewById(R.id.name);
password = (EditText) findViewById(R.id.password);
login = (Button) findViewById(R.id.login);
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
TextView uiUpdate = (TextView) findViewById(R.id.output);
String outputasync = uiUpdate.getText().toString();
String serverURL = "http://192.168.1.105/myapp/text.php";
LongOperation longOperation = new LongOperation(MainActivity.this, uiUpdate);
longOperation.execute(serverURL, outputasync);
}
});
}
Note: doInBackground still working with "return = null" because im just using it for read the data inside the server, not for retrieve it anywhere.
You should not be calling onPostExecute manually from your code. Calling execute on the asynctask should suffice. onPostExecute will automatically be called when the asynctask finishes its work.
First about the problem in your Activity:
LongOperation longOperation = new LongOperation(MainActivity.this);
longOperation.execute(serverURL);
longOperation.onPostExecute(uiUpdate);
longOperation.execute(serverURL); is an asynchronous method. Which means your program will call longOperation.onPostExecute(uiUpdate); right after execute method without waiting for the results in doInBackground.
You can't do that and you shouldn't do that. onPostExecute is automatically called after doInBackground returns result (which you return null right now.)
LongOperation longOperation = new LongOperation(MainActivity.this);
longOperation.execute(serverURL);
longOperation.onPostExecute(uiUpdate);
Now the solution:
1) doInBackground return type should always be equal to onPostExecute parameter.
If you are return String then onPostExecute will look like this:
protected void onPostExecute(String string) {
}
2) How to set your TextView that is in your Activity. The simplest way is to pass activity variable to LongOperation constructor and use that for accessing TextView in onPostExecute.
3) How to send data to onPostExecute? You have to return it in method:
#Override
protected String doInBackground(String... urls) {
// do anything here.
return "String"; //Since return type is String. You can change that you anything and make sure it matches `onPostExecute` parameter type.
}
Your doInBackground() method only returns null. Ever.
Your onPostExecute() method isn't called because it isn't overriding AsyncTask's onPostExecute() method, which would take a String argument

Categories