Android Http API - java

I am trying to write a Http API in android. I am using a AsyncTask to run the calls to my web service.I am not interested in updating the UI, instead all I want is the data to use in my application logic. This is what I have so far:
public class DataManager{
public static String result;
public DataManager ()
{
}
public String get ()
{
User user = new User ();
user.execute("http://someuri/service/users/id/21001");
return user.getResult();
}
}
public class User extends AsyncTask <String,Void,String>{
private String result;
#Override
protected String doInBackground(String... arg0)
{
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet (arg0[0]);
try
{
HttpResponse response = client.execute (get);
if (response.getStatusLine().getStatusCode () == 200)
{
HttpEntity entity = response.getEntity();
return EntityUtils.toString(entity);
}
}
catch (ClientProtocolException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
this.result = result;
}
public String getResult ()
{
return result;
}
}
I want a typical call to be:
DataManager manager = new DataManager ();
String value = manager.get ();
But when I run this I get back null. What is causing this and how can I refactor this code to get the desired behavior.

The whole idea of a thread is that it runs concurrently. Basically, here's what you're doing:
User user = new User (); // Create User object
user.execute("http://someuri/service/users/id/21001"); // Start thread
return user.getResult(); // Return thread result
However, there is no time for the thread to run between "start" and "return result".
I would suggest using some kind of callback; first, make get() return void, and remove the return statement. Then, you pass in some object which implements YourCallback, and then call onCallback(result) from within onPostExecute().
Your calling code would then look like this:
DataManager x = new DataManager();
x.get(new YourCallback() {
public void onCallback(String result) {
// ...
}
});
There is a much fuller example in this fantastic answer.

Related

Https request reaching twice to server android

My post request code as follows
When post request to the server it reach twice in to the server
and i am sure call httpRequest once.When i call once the request reach server twice or thrise;
private void invokePostOrderRestService(
final RestPostDataCallback<Order> callback,
final RequestOrder requestOrder) {
String URL = BASE_URL + "postOrder";
Log.e("post ordercccccc", "orderPosted");
JSONObject jsonObject = convertOrderRequestToJson(requestOrder);
if (jsonObject != null) {
OrderProApplication
.getContext()
.getRestClient()
.postJsonObject(URL, jsonObject,
new ResponseListener<JSONObject>() {
#Override
public void onSuccess(JSONObject response) {
// TODO Auto-generated method stub
Log.e("Order Post Success","Post Order Successssssssssssssssss");
String status = "";
try {
status = response.getString("status");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (status.equals("OK")) {
callback.onRestPostDataCompleted(
ResultCode.RESULT_OK, null);
} else {
callback.onRestPostDataCompleted(
ResultCode.RESULT_FAIL, null);
}
}
#Override
public void onRestError(RestError error) {
// TODO Auto-generated method stub
Log.e("Order Post Failed","Post Order failedddddddddddddddddddd");
i = i + 1;
callback.onRestPostDataCompleted(
ResultCode.RESULT_FAIL, null);
}
});
} else {
callback.onRestPostDataCompleted(ResultCode.RESULT_FAIL, null);
}
}
And am pretty sure my url is correct.
Thanks:).
Most likely your method is being called twice. Check where you are calling out the method - this might be occurred thanks to misunderstanding of Activity/Fragment lifecycle.
Put a print in the beginning of your invoke method and check, if it prints out twice.

JAVA: How to listen to calling of event handler/How to get returned result of an event handler?

I am creating an Android chat application wherein I am using WebSockets and on top of that I want to create a custom implementation of Application protocol.
I am stuck in a situation.
Essentially, what I want is a way to know that an event handler method has been called in another class, fire up my own method in my class based on that and then get the result of that event handler method in my class.
How is that possible?
I researched a lot and found something like binding, event emitters, etc. Can someone point me to the right direction and provide some resources from where I can learn this technique?
This is what I have done so far:
public void connect(){
try {
setUpWebSocketHandler(handler);
mConnection.connect(wsuri, handler);
}
catch (WebSocketException e) {
Log.d("exception", e.toString());
}
}
public void setUpWebSocketHandler(WebSocketHandler handler)
{
handler = new WebSocketHandler(){
//first method for websockethandler
#Override
public void onOpen() {
//here i create a json format string to be sent to my server that returns something afterwards
String output = json.toString();
Log.d("OUTPUT+" , output);
Log.d("onOpen", "Status: Connected to " + wsuri);
mConnection.sendTextMessage(output);
}
//second method for websockethandler
#Override
public void onTextMessage(final String payload) {
Log.d("onTextMessage", "Response: " + payload);
JSONObject jsonObj = null;
try {
jsonObj = new JSONObject(payload);
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
String type = jsonObj.getString("type");
switch (type) {
case "xxx":
//authEvent
System.out.println("xxx");
break;
case "yyy":
//userOnlineEvent
System.out.println("yyy");
break;
case "zzz":
System.out.println("zzz");
break;
case "userListToken":
userList = getUserList(payload);
break;
default:
System.out.println("DefaultCase");
break;
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//third method for websockethandler
#Override
public void onClose(int code, String reason) {
Log.d("onClose", "Connection lost.");
}
};
}
public String getUserList(final String payload)
{
final Thread connectthread;
connectthread = new Thread(
new Runnable()
{
public void run()
{
try {
//here i create a URL, send post request to it and i get a response with userlist
HttpClient client = new DefaultHttpClient();
HttpGet post = new HttpGet(url);
HttpResponse response = client.execute(post);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
while ((userList = rd.readLine()) != null) {
System.out.println(userList);
Log.d("HTTP GET RESPONSE", "Response: " + userList);
}
} catch (JSONException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
);
connectthread.start();
try
{
connectthread.join();
}
catch (Exception e)
{
Log.i("error","Error!!");
}
System.out.println("userListToken");
return userList;
}
I have another question. I got the userList using callbacks....The problem now is:
private class ProcessLogin extends AsyncTask<String, Void, String> {
private ProgressDialog pDialog;
String uname,password;
#Override
protected void onPreExecute() {
super.onPreExecute();
uname = txtUsername.getText().toString();
password = txtPassword.getText().toString();
pDialog = new ProgressDialog(LoginActivity.this);
pDialog.setTitle("Contacting Servers");
pDialog.setMessage("Logging in ...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected String doInBackground(String... args) {
String user = null;
ifly.connect();
user = userList;
return user;
}
#Override
protected void onPostExecute(String user) {
try {
if(user != null){
//Intent i = new Intent("com.example.tabmainactivity");
Log.d("Got it", "Response: " + userList);
pDialog.dismiss();
//startService(new Intent(getApplicationContext(),iFlyChatMessage.class));
//startActivity(i);
//finish();
}else{
// username / password doesn't match
pDialog.dismiss();
Toast.makeText(getApplicationContext(),
"Incorrect username/password", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void processMessage(String userList)
{
this.userList = userList;
}
I want the userList in postExecute so that i can send this userList to another activity. How do i stop doinbackground() to wait for callback to finish. If I use thread.sleep, the whole process stops, not even connect works.
Thanks
You can declare an interface somewhere, make your event handler accept an instance of this interface, then create an anonymous class implementing this interface while passing that instance in your handler's registration with event source.
Something like below:
public class MyClass{
...
...
component.addXXXListener(new EventHandler(new MyInterface() {
#Override
public void doSomething() {
callMethod();
}
}));
...
...
public void callMethod() {
...
...
}
I hope you got the point.
I'm not sure that I understood you correctly.
You should use callback object.
Something like:
public interface MessageProcesor{
public void processMessage(String message);
}
Your activity should implement this interface.
And you should have MessageProcesor field in your "client" class.
Your code should look something like this:
private MessageProcesor callback;
public void setUpWebSocketHandler(WebSocketHandler handler)
{
handler = new WebSocketHandler(){
//first method for websockethandler
#Override
public void onOpen() {
//here i create a json format string to be sent to my server that returns something afterwards
String output = json.toString();
Log.d("OUTPUT+" , output);
Log.d("onOpen", "Status: Connected to " + wsuri);
mConnection.sendTextMessage(output);
}
//second method for websockethandler
#Override
public void onTextMessage(final String payload) {
Log.d("onTextMessage", "Response: " + payload);
JSONObject jsonObj = null;
try {
jsonObj = new JSONObject(payload);
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
String type = jsonObj.getString("type");
switch (type) {
case "xxx":
//authEvent
System.out.println("xxx");
break;
case "yyy":
//userOnlineEvent
System.out.println("yyy");
break;
case "zzz":
System.out.println("zzz");
break;
case "userListToken":
userList = getUserList(payload);
callback.processMessage(userList);
break;
default:
System.out.println("DefaultCase");
break;
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//third method for websockethandler
#Override
public void onClose(int code, String reason) {
Log.d("onClose", "Connection lost.");
}
};
}
public String getUserList(final String payload)
{
final Thread connectthread;
connectthread = new Thread(
new Runnable()
{
public void run()
{
try {
//here i create a URL, send post request to it and i get a response with userlist
HttpClient client = new DefaultHttpClient();
HttpGet post = new HttpGet(url);
HttpResponse response = client.execute(post);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
while ((userList = rd.readLine()) != null) {
System.out.println(userList);
Log.d("HTTP GET RESPONSE", "Response: " + userList);
}
} catch (JSONException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
);
connectthread.start();
try
{
connectthread.join();
}
catch (Exception e)
{
Log.i("error","Error!!");
}
System.out.println("userListToken");
return userList;
}
You can pass "callback" as constructor param or via setter method.
Hope this helps.

Android AsyncTask getting an exception null

In the AsyncTask android. When calling a method in another class gets an exception which equals to null in the doInBackGround() task.
Even the hard coded inside the rest.request(url, method, json) doesn't work
protected JSONArray doInBackground(Void... arg0) {
try {
return rest.request(url, method, json); // <-- returns json array
} catch (Exception e) {
this.e = e;
}
return null; // <--- returning this null
}
Other things are like this,
private class doRequest extends AsyncTask<Void, JSONArray, JSONArray>
protected void onPostExecute(JSONArray data)
/*rest client class*/
public class AndrestClient {
// The client to use for requests
DefaultHttpClient client = new DefaultHttpClient();
public JSONArray request(String url, String method, String json) throws RESTException {
if (method.matches("GET")) {
return get(url);
} else if (method.matches("POST")) {
return post(url, json);
} else if (method.matches("PUT")) {
//return put(url, data);
} else if (method.matches("DELETE")) {
//return delete(url);
}
throw new RESTException("Error! Incorrect method provided: " + method);
}
public JSONArray get(String url) throws RESTException {
String jsonjr = "['Chanuthi','Damsith','Dunili','Isath','Minuka','Uvin','Vidath']";
JSONArray jsonAraay = null;
try {
jsonAraay = new JSONArray(jsonjr);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return jsonAraay;
}
}
The exception I got is e=null. All the other things work properly. When I am hard coding the result inside in the doInBackGround it works properly. Also the rest client get method returns the exact thing.
It appears you're using AsyncTask improperly. Firstly, you must subclass/nest your AsyncTask as per the Android documentation:
http://developer.android.com/reference/android/os/AsyncTask.html
In addition, you should follow the fundamental rules for calling methods of an outter class from a nested class.
There are some alternatives, like:
Create the AndrestClient object in onPreExecute() of the AsyncTask
Pass the AndrestClient object to the doInBackground as a parameter, then call its methods by doing something like this in the outter class:
doRequest.execute(rest);

need to return value from AsyncTask [duplicate]

This question already has answers here:
AsyncTask return value
(4 answers)
Closed 9 years ago.
I am calling soap webservice and need to display what is returned. but I couldnt do it because AsyncTask is complex and I dont know how to use it properly. would you please tell me how to return data from the called function via asynctask?
here is my code
public class WebserviceTool {
private final String NAMESPACE = "http://tempuri.org/";
private final String URL = "http://192.168.0.11:9289/Service1.asmx";
private final String SOAP_ACTION = "http://tempuri.org/get_currency";
private final String METHOD_NAME = "get_currency";
public static void main(String[] args) {
// TODO Auto-generated method stub
}
public String execute_barcode_webservice(String s1, String s2) {
//Create request
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("date",s1);
request.addProperty("cur_code",s2);
//Create envelope
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.encodingStyle = SoapEnvelope.ENC;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
Object response;
try {
androidHttpTransport.call(SOAP_ACTION, envelope);
response = (Object) envelope.getResponse();
Log.i("my_error", response.toString());
} catch (Exception e) {
Log.i("my_error", e.getMessage().toString());
}
return "testarif";
}
public class AsyncCallWS extends AsyncTask<String, Void, Void> {
#Override
protected Void doInBackground(String... params) {
try {
execute_barcode_webservice(params[0], params[1]);
} catch (Exception e) {
// TODO: handle exception
}
return null;
}
#Override
protected void onPostExecute(Void result) {
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
}
this is the function execute_barcode_webservice() that does all the job and returns data. but since I call execute_barcode_webservice() view AsyncTask, I dont know how to return with it. how can I do it?
The result of the async task execution is the response object produced by execute_barcode_webservice(). However, don't think about the async task as something that will execute and return a value to you. Instead, inside the method onPostExecute() you must take the response object and process it (extract its values and display them in a list, or whatever you want to do with it). The async task is just a way to execute some code in a separate thread then go back to the main thread (the UI thread) and process the results, which is done in onPostExecute().
My suggestion: rewrite execute_barcode_webservice() to return a response object instead of a String (an object that can be null if the operation fails) and pass that object to the onPostExecute() method. You will have to change the async task to:
public class AsyncCallWS extends AsyncTask<String, Void, Object> {
#Override
protected Object doInBackground(String... params) {
Object response = null;
try {
response = execute_barcode_webservice(params[0], params[1]);
} catch (Exception e) {
// TODO: handle exception
}
return response;
}
#Override
protected void onPostExecute(Object response) {
if (response != null) {
// display results in a list or something else
}
}

Doing networkprocesses on the Main UI

My Android App needs some basic data to run. This data is downloaded from a server using JSON. In Xcode I simply used the sendsynchronous request but I noticed that Eclipse gives me a error when i do networking on the main ui.
Found a lot of stuff on asynctask but i want my app to wait till the required data is downloaded (synchronous?).
I tried using asynctask .execute().get() and setting the variables in onPostExecute but when I return the variable I get a NullPointerException. Does someone know how to make this work? I really need this data before the app can run so I want my app to wait till the data is downloaded.
MainActivity calls this:
SingletonClass appIDSingleton = SingletonClass.getInstance();
this.ID = appIDSingleton.getAppID();
Singleton Class:
public String getAppID() {
try {
new DownloadAppID().execute(APP_ID_URL).get(5000, 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();
}
return AppID; //AppID is still NULL (because the download isnt finished yet?)
}
private class DownloadAppID extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String response = "";
for (String url : urls) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse execute = client.execute(httpGet);
InputStream content = execute.getEntity().getContent();
BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null) {
response += s;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return response;
}
#Override
protected void onPostExecute(String result) {
System.out.println(result);
AppID = result;
}
}
You need to understand that your getAppID method can't return a result that is going to be computed asynchronously.
You could for instance provide a listener to your async task in order to notify when app ID is available:
SingletonClass appIDSingleton = SingletonClass.getInstance();
appIDSingleton.getAppID(new AppIdDownloadListener() {
#Override
public void appIDAvailable(String appId) {
this.ID = appId;
}
});
public void getAppID(AppIdDownloadListener listener) {
try {
new DownloadAppID(listener).execute(APP_ID_URL).get(5000, 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();
}
}
public interface AppIdDownloadListener {
public void appIDAvailable(String appId);
}
private class DownloadAppID extends AsyncTask<String, Void, String> {
private AppIdDownloadListener listener;
public DownloadAppID(AppIdDownloadListener listener) {
this.listener = listener;
}
#Override
protected String doInBackground(String... params) {
/* Your stuff here */
}
#Override
protected void onPostExecute(String result) {
System.out.println(result);
listener.appIDAvailable(result);
}
}

Categories

Resources