how can i run Webservice code in Thread? - android

I wanna get some data from server with this code :
public class Webservice {
public static String readUrl(String url, ArrayList<NameValuePair> params) {
try {
HttpClient client = new DefaultHttpClient();
HttpPost method = new HttpPost(url);
if (params != null) {
method.setEntity(new UrlEncodedFormEntity(params));
}
HttpResponse response = client.execute(method);
InputStream inputStream = response.getEntity().getContent();
String result = convertInputStreamToString(inputStream);
return result;
}
catch (ClientProtocolException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
return null;
}
private static String convertInputStreamToString(InputStream inputStream) {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder builder = new StringBuilder();
String line = "";
while ((line = reader.readLine()) != null) {
builder.append(line);
}
return builder.toString();
}
catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
but there is some delay and pause in the application , so i wanna run this code in the Thread , but when i tried to do it , i got some error , for example i couldn't return the result or ...

Take a look at AsyncTask:
Network operations can involve unpredictable delays. To prevent this
from causing a poor user experience, always perform network operations
on a separate thread from the UI. The AsyncTask class provides one of
the simplest ways to fire off a new task from the UI thread. For more
discussion of this topic, see the blog post Multithreading For
Performance.
In the following snippet, the myClickHandler() method invokes new
DownloadWebpageTask().execute(stringUrl). The DownloadWebpageTask
class is a subclass of AsyncTask.
public class HttpExampleActivity extends Activity {
private static final String DEBUG_TAG = "HttpExample";
private EditText urlText;
private TextView textView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
urlText = (EditText) findViewById(R.id.myUrl);
textView = (TextView) findViewById(R.id.myText);
}
// When user clicks button, calls AsyncTask.
// Before attempting to fetch the URL, makes sure that there is a network connection.
public void myClickHandler(View view) {
// Gets the URL from the UI's text field.
String stringUrl = urlText.getText().toString();
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
new DownloadWebpageTask().execute(stringUrl);
} else {
textView.setText("No network connection available.");
}
}
// Uses AsyncTask to create a task away from the main UI thread. This task takes a
// URL string and uses it to create an HttpUrlConnection. Once the connection
// has been established, the AsyncTask downloads the contents of the webpage as
// an InputStream. Finally, the InputStream is converted into a string, which is
// displayed in the UI by the AsyncTask's onPostExecute method.
private class DownloadWebpageTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
// params comes from the execute() call: params[0] is the url.
try {
return downloadUrl(urls[0]);
} catch (IOException e) {
return "Unable to retrieve web page. URL may be invalid.";
}
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(String result) {
textView.setText(result);
}
}
... }

Related

Call Async Webservice From For Loop

When I call a webservice from a for loop to insert/update data into MySQL using PHP only the last item gets inserted/updated because (i think) the for loop completes quicker than the webservice, how can I delay my for loop or achieve a webservice call for each item returned in the for loop one after another.
For Loop Code:
for (int i = 0; i < lv.getCount(); i++) {
view = lv.getAdapter().getView(i, lv.getChildAt(i), lv);
if (view != null) {
// Getting my views
tvItem = (TextView) view.findViewById(R.id.tvItem);
strItem = tvItem.getText().toString();
//Call AsyncTask
accessWebService();
}
}
Webservice:
private class Webservice extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(params[0]);
try {
HttpResponse response = httpclient.execute(httppost);
jsonResult = inputStreamToString(response.getEntity().getContent()).toString();
}
catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private StringBuilder inputStreamToString(InputStream is) {
String rLine = "";
StringBuilder answer = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
try {
while ((rLine = rd.readLine()) != null) {
answer.append(rLine);
}
}
catch (IOException e) {
}
return answer;
}
#Override
protected void onPostExecute(String result) {
try{
ld();
}catch (Exception e){
}
}
}// end async task
public void accessWebService() {
Webservice task = new Webservice();
//Update MySQL Using PHP
}
When you want to insert/update all data from for loop you must use callback like interfaces. Once you implement this it will wait for completing the process. Once completed it will call success or error method. Based on this you insert/update another record.
interface DataCallback {
fun onSuccess(result: Any)
fun onError(error: Any)
}
public void getCountries(new DataCallback(){
#Override
public void onSuccess(Object result){
// insert/update next record
}
#Override
public void onError(Object error){
// show error message
}
});
This is just example. You should convert it based on your need. Thanks.

HttpURLConnection crashes application

I want to receive and send data with a web server but the code does not work
What do I do for this code to work?
Note this code inside onCreate
try {
URL url = new URL("http://myweb.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
InputStream Stream = connection.getInputStream();
InputStreamReader reader = new InputStreamReader(Stream);
BufferedReader b = new BufferedReader(reader);
StringBuilder s = new StringBuilder();
String str ="";
while ((str = b.readLine())!=null) {
s.append(str);
}
String data = s.toString();
TextView myText = (TextView) findViewById(R.id.Text);
myText.setText(data);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Make sure that you do network-related tasks on a separate thread in Android. Also, check that you have the INTERNET permission set.
If you want to then update the UI from another thread, you have to use
runOnUiThread (new Runnable () {
public void run() {
//update ui in here
}
}
All your code runs in Main thread which should be always used for setting up the UI and to listen for UI events such as on click listeners.
Network calls are not allowed on this thread as they might take long time. Use AsyncTask API of android which is designed for running code in separate thread.
Create a class like one below for all GET request tasks.
public class DownloadTask extends AsyncTask<String, Void, Integer> {
private String TAG = "InDownloadTask";
private DownloadCallback callback;
private String data;
public DownloadTask(DownloadCallback cb){
callback = cb;
}
#Override
protected Integer doInBackground(String... params) {
Integer result = 0;
HttpURLConnection urlConnection;
try {
URL url = new URL(params[0]);
urlConnection = (HttpURLConnection) url.openConnection();
int statusCode = urlConnection.getResponseCode();
if (statusCode == 200) {
BufferedReader r = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
response.append(line);
}
data = response.toString();
result = 1;
} else {
result = 0;
}
} catch (Exception e) {
Log.d(TAG, e.getLocalizedMessage());
}
return result;
}
#Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
callback.onFinishDownload(data, integer);
}
}
Create a callback interface that we use for the above class.
public interface DownloadCallback {
public void onFinishDownload(String data, Integer result);
}
Now from your activity onCreate
String url = "http://myweb.com/";
new DownloadTask(new DownloadCallback() {
public void onFinishDownload(String data, Integer result) {
if(result == 1)
myText.setText(data);
else
myText.setText("Error");
}
}).execute(url);
If you have many network related operations, use a Network library such as Volley which will take care of this.

HTTP Client on android app returning blank screen

I wrote a simple method to get some string data using the apache HTTPClient, however it returns a blank screen when I run it on my phone; I'm trying to display the data in a textarea. The manifest has the internet permission. Can anybody point out what I could be doing wrong?
public String getInternetData() throws Exception
{
BufferedReader in = null;
String data = null;
try
{
HttpClient client = new DefaultHttpClient();
URI website = new URI("http://www.yahoo.com");
HttpGet request = new HttpGet();
request.setURI(website);
HttpResponse response = client.execute(request);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String l = "";
String nl = System.getProperty("line.separator");
while((l=in.readLine())!=null){
sb.append(l+nl);
}
in.close();
data = sb.toString();
return data;
}finally{
if(in !=null){
try{
in.close();
return data;
}catch (Exception e){
e.printStackTrace();
}
}
}
}
for completeness, I am adding the code I use to see the data.
public class MainActivity extends Activity {
TextView httpStuff;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
httpStuff = (TextView) findViewById(R.id.tvHttp);
GetMethodEx test = new GetMethodEx();
String returned;
try {
returned = test.getInternetData();
httpStuff.setText(returned);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
You are probably getting Network on UI thread error, and because it is in a try catch, the app isnt crashing
you are supposed to invoke network operations only in background threads, or AsyncTasks which are great for that
there is nothing wrong with your HTTP client and request data, the problem indeed lies in your onCreate method
try rewriting it this way
public class MainActivity extends Activity {
TextView httpStuff;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
httpStuff = (TextView) findViewById(R.id.tvHttp);
AsyncTask<Void,Void,String>getDataTask = new AsyncTask<Void,Void,String>(){
#Override
protected String doInBackground(Void... params){
GetMethodEx test = new GetMethodEx();
String returned = test.getInternalData();
return returned;
}
#Override
protected void onPostExecute(String returned){
httpStuff.setText(returned);
}
}
}
getDataTask.execute();
}

AsyncTask usage on Android

I use AsnycTask to connect URL and parse the return xml:
class Connecting extends AsyncTask<String, String, String> {
private String URLPath = "";
private HttpURLConnection Connection;
private InputStream InputStream;
private boolean Return1 = false;
private int Return2 = -1;
public Connecting (String fn, String u) {
FileName = fn;
URLPath = u;
Connection = null;
InputStream = null;
Return1 = false;
Return2 = -1;
execute();
}
public boolean getReturn1() {
return Return1;
}
public int getReturn2() {
return Return2;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... aurl) {
try {
URL url = new URL(URLPath);
Connection = (HttpURLConnection)url.openConnection();
Connection.setConnectTimeout(10000);
Connection.setReadTimeout(10000);
Connection.setDoInput(true);
Connection.setUseCaches(false);
Connection.connect();
InputStream = Connection.getInputStream();
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String unused) {
super.onPostExecute(unused);
try {
InputStreamReader fsr = new InputStreamReader(InputStream);
BufferedReader br = new BufferedReader(fsr);
String line = "";
while((line = br.readLine()) != null) {
//parse Reture1 and Return2
}
}
catch(Exception e) {
e.printStackTrace();
}
Connection = null;
}
}
And I use below code to call it:
Connecting con = new Connecting(Name, URL);
System.out.println("Return1 " + con.getReturn1());
System.out.println("Return2 " + con.getReturn2());
It will get false and -1, which the init value.
And connect URL after print message.
I want to get the value which has connect success and parse from the xml.
How can I do it?
AsyncTask is a class that helps to run in background. You can use it if you want to access to remote server using for example HTTP connection.
In doBackground method you have to the the "heavy" task, the one that requires time and could block the UI. When you finish at the end of doBackground you have to return the value that is the result of the task.
Then in the onPostExecute you use this result to update for example the UI.
In your case it seems to me you aren't using correctly the AsyncTask. First of all you return null in doBackground and dont set return1 and return2 as you should.
And in onPostExecute you read the response while yuo should do it in doBackground.
There's another method you can override called onPreExecute that is called before doBackground method.
In my blog i've an example how to use AsyncBackground in this case and it could help you. If you like give a look here
The AsyncTask runs (as the name says) asynchronously to the main-thread.
If you want to happen something after the task is done, you have to put that code in the onPostExecute() method.
So you may put the System.out there.

Android Programming: HTTP GET REQUEST NOT WORKING

I require a GET reequest from my own server to be extracted from the web and then displayed on screen with a TextView.
I have set up a GET Request.
public class GetMethodEx {
public String getInternetData() throws Exception{
BufferedReader in = null;
String data = null;
try
{
HttpClient client = new DefaultHttpClient();
URI website = new URI("http://www.mybringback.com");
HttpGet request = new HttpGet();
request.setURI(website);
HttpResponse response = client.execute(request);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String l = "";
String nl = System.getProperty("line.separator");
while ((l = in.readLine()) !=null){
sb.append(l + nl);
}
in.close();
data = sb.toString();
return data;
} finally{
if (in != null){
try{
in.close();
return data;
}catch (Exception e){
e.printStackTrace();
}
}
}
}
}
And I have set up on my main thread to extract the information and display it in a text view.
public class Home extends Activity {
TextView httpStuff;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.httpexample);
httpStuff = (TextView) findViewById(R.id.tvhttp);
GetMethodEx test = new GetMethodEx();
String returned;
try {
returned = test.getInternetData();
httpStuff.setText(returned);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
However, the Textview doesnt seem to change?
Can someone help me please.
Change your code using AsyncTask if you want to make any network operation from Ui Thread as:
public class Home extends Activity {
TextView httpStuff;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.httpexample);
httpStuff = (TextView) findViewById(R.id.tvhttp);
new LongOperation().execute("");
}
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
GetMethodEx test = new GetMethodEx();
String returned;
try {
returned = test.getInternetData();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return returned;
}
#Override
protected void onPostExecute(String result) {
// Update Ui here
httpStuff.setText(result);
}
}
}
Android OS > = 3.0
does not allow NetworkRequest on main UI thread.
Use AsyncTask to call webrequest.

Categories

Resources