Android - Open URL in background - android

There is this website for example http://website.com You can like stuff there, with a link like this for example: http://website.com/3020/hype. You have to go to that link to get the article (3020) liked. You can only like stuff when loged in.
I have this:
HttpClient client = new DefaultHttpClient();
String getURL = "http://website.com/3020/hype/";
HttpGet get = new HttpGet(getURL);
HttpResponse responseGet = client.execute(get, cookieStuff);
Where cookieStuff is the cookie string I got from loggin in.
This works, but it takes ages. Is there another option?

Yes there is a nother option.. Internet connections and Database Connection should made in a AyncTask or Handler.. This will improve the time taken for connection (the connections will make in Background)..
here is a example for an async task:
private class YourTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... s) {
//Here you have to make the loading / parsing tasks
//Don't call any UI actions here. For example a Toast.show() this will couse Exceptions
// UI stuff you have to make in onPostExecute method
}
#Override
protected void onPreExecute() {
// This method will called during doInBackground is in process
// Here you can for example show a ProgressDialog
}
#Override
protected void onPostExecute(Long result) {
// onPostExecute is called when doInBackground finished
// Here you can for example fill your Listview with the content loaded in doInBackground method
}
}
To execute an AsyncTask:
new YourTask().execute("");

Related

Android login and how to make a network blocking call

I get a username from a login screen. I want to make a call to a web service to validate user. The problem is that I am getting the error:
android.os.NetworkOnMainThreadException
I know why I'm getting it. I'm making a network call on the main thread.
The problem is that I don't want to use AsyncTask. I don't want the user to be able to sign in BEFORE I get a response from the web service.
How do I get around this?
You can start an AsyncTask when the user opens the first Activity, with a "Waiting" fragment. When the AsyncTask finished, you can switch to the "Login" fragment.
You can use AsyncTask as shown below to sign in only when you get a response from the web service.
class SignInAsyncTask extends AsyncTask<Void, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Display a progress bar saying signing in or something
}
#Override
protected String doInBackground(Void... params) {
// Call your web service
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// Sign in if the credentials are okay, otherwise show some error message to the user
}
}
If you really don't want to use AsyncTask you could start a new Thread and put your logic here.
new Thread(new Runnable() {
public void run() {
// Sign in validation
}
}).start();

ProgressDialog in AsyncTask onPreExecute, but it appears after doInBackground

This is part of my application. (You can run code below as an isolated application) On that website (url), using php language, parse some numbers from other website, and make an array and encode it to JSON array, and show.
But, with the code below (without dismiss function!) ProgressDialog appears after doInBackground.
When I add dismiss function to onPostExecute like below, it never appears. But When I set log for checking dialog window, it says that there was an dialog.
I heard that doInBackground freezes UI, but it freezes before dialog is shown.
Other similar questions have found solution, erasing .get() from mAsyncTask().execute().get(), but I don't have any get() in my code.
Boolean variable loadfinish is for waiting finishing asynctask, to show results from that website after asynctask. If I delete
while(loadFinish == false)
there, it automacally appears and disappears very well, but I can't show result immediately...
Add) I found that it takes several seconds to dialog appear after doInBackground... why?!
Add2) I've tried to move dialog codes before and after new mAsyncTask().execute(), but it doesn't work too...
public class MainActivity extends Activity {
boolean loadFinish;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button start = (Button) findViewById(R.id.start);
//just a button for starting asynctask
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
loadFinish = false;
new mAsyncTask().execute();
// get and make json array to java array
while (loadFinish == false)
;
}
});
// add array to Custom_List_Data, and set custom row_adapter to listView.
// if I delete while(loadFinish == false), array with initial data is added.
}
private class mAsyncTask extends AsyncTask<String, String, String> {
ProgressDialog dialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(MainActivity.this);
dialog.setMessage("asdf");
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.show();
}
#Override
protected String doInBackground(String... params) {
String url = "http://songdosiyak.url.ph/MouiRate/etoos/3/main/";
String response_str = "";
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(url);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
try {
response_str = client.execute(request, responseHandler);
} catch (ClientProtocolException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
loadFinish = true;
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
dialog.dismiss();
}
}
}
Sorry for my poor English language skill and thank you for reading!
As Gabe mentioned you don't need the loop, all you need is some more understanding what the async methods should do.
You introduced the result, because you want to display the result. All you have to do is to return your response_str in doInBackground. It will be then available to you as a param to onPostExecute where you can easily display it, or do whatever you need to do with it.
So to summarize:
Remove the loop
Return value response_str or whatever from doInBackground
Display value in onPostExecute
And remove loadFinish variable as its not needed at all
Hope that helps.
Because you're using an AsyncTask totally wrong. You're busy looping waiting for it to finish. NEVER do that- if you're doing that there's no point in using an AsyncTask. At any rate, the reason it won't appear is that the UI doesn't update until the UI thread returns to the event loop inside the Android Framework and runs the drawing code, which happens after onClick returns. So you won't draw until your busy loop exits, which happens after doInBackground finishes.
The solution is to remove the loop waiting for the AsyncTask to finish in your onClick. If you have logic that needs to run after it, put it in onPostExecute.
It may be worth looking into using an async library.
Using a library to help handle async callbacks can be super helpful for this as you can start the spinner, call your api, then stop the spinner in either the onSuccess function, or your success callback method in your class.
This is the one I usually use:
LoopJ's Async HTTP Callback Library
This will handle GET and POST requests with a lot of cool features such as custom timeouts, JSON format, onSuccess() and onFailure() methods, etc. There's a lot of working examples of this library too. I've used it in all my apps and haven't had any problems yet!
Hopefully this helps.

Run New Thread on Timer Android

I've been working on an android app which regularly checks a mysql database using JSON and everything works fine with my code.
Im having trouble running this as a timer as it only runs once and then stops.
The only code i managed to get working runs the http request on the UI thread which freezes up.
Any help would be most appreciated.
Thank in advance,
#Override
protected void onCreate(Bundle savedInstanceState) {
...
checkUpdate.start();
...
}
private Thread checkUpdate = new Thread() {
public void run() {
try {
// my code here to get web request to return json string
}
String response = httpclient.execute(httppost, responseHandler);
mHandler.post(showUpdate);
}
...
}
private Runnable showUpdate = new Runnable(){
public void run(){
try{
// my code here handles json string as i need it
Toast.makeText(MainActivity.this,"New Job Received...", Toast.LENGTH_LONG).show();
showja();
}
}
}
private void showja(){
Intent i = new Intent(this, JobAward.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
finish();
}
As #Raghunandan suggested, the standard way to perform work in the background on Android, and then modify the UI when that work is done, is using AsyncTask.
First define a new subclass of AsyncTask:
private class JsonRequestTask extends AsyncTask<HttpUriRequest, Void, String> {
protected String doInBackground(HttpUriRequest... requests) {
// this code assumes you only make one request at a time, but
// you can easily extend the code to make multiple requests per
// doInBackground() invocation:
HttpUriRequest request = requests[0];
// my code here to get web request to return json string
String response = httpclient.execute(request, responseHandler);
return response;
}
protected void onPostExecute(String jsonResponse) {
// my code here handles json string as i need it
Toast.makeText(MainActivity.this, "New Job Received...", Toast.LENGTH_LONG).show();
showja();
}
}
and then you would use the task like this, instead of your Thread:
#Override
protected void onCreate(Bundle savedInstanceState) {
...
JsonRequestTask task = new JsonRequestTask();
task.execute(httppost);
...
}
You may run the task again by simply creating a new JsonRequestTask() and calling its execute() method.
A common practice for a simple async task like this is to make it a private inner class within the Activity class that uses it (if only one Activity needs it). You may need to change the scope of some of your activity's variables so that the inner class may use them (e.g. move local variables to member variables).

Android I can't get xml from url

I'm trying to get an xml from a url, but I have a bug in HttpResponse.
The URL is for example as follows:
http://maps.googleapis.com/maps/api/directions/xml?origin=43.364876,-5.8654205&destination=43.545686,-5.664482&sensor=true
And my code is:
public String getXML (String url){
String result = null;
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpPost = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
result = EntityUtils.toString(httpEntity);
} catch (Exception ex) {
Toast errorToast =
Toast.makeText(getApplicationContext(),
"Error reading xml", Toast.LENGTH_LONG);
errorToast.show();
}
return result;
}
I've already set the internet permission in the manifest.
The error is in the line:
HttpResponse httpResponse = httpClient.execute(httpPost);
and shows an error:
android.os.NetworkOnMainThreadException
Thank you
You should create a new thread as fetching the data could take a long time, thus blocking the UI thread. This is reason why you get android.os.NetworkOnMainThreadException.
Try this,
new Thread(new Runnable() {
#Override
public void run() {
// Your code here.
}
}).start();
Alternative to this solution is using AsyncTask, which is provided in android. It has doInBackground method which runs on a background thread.
Instead of calling getXML(); directly, you write this snippet in your main method:
{
...
String[] params = new String[]{url};
AsyncPostData apd = new AsyncPostData ();
apd.execute(params);
...
}
Define your Async Task like below:
private class AsyncPostData extends AsyncTask<String, Void, Void> {
#Override
protected Void doInBackground(String... params) {
getXML (params[0])
return null;
}
}
I think we have a same query here
cant get xml file from an URL in android
I'll just repost this from a different question asked earlier today:
You're trying to run a network request on the main UI thread. Android does not allow you to do that since 3.0 (I believe). Doing so causes your UI to lock up until the request is completed, rendering your app useless during the execution of the request.
You'll either have to run your request in a new Thread or an ASyncTask, to take the load of the UI thread. You can find more info on how to use multiple threads here.
Android Devices with 4+ OS versions not allows to call webservices from main activity.
your have HTTP request on activity, so you have got "android.os.NetworkOnMainThreadException"
I recommend you go for the AsyncTask solution. It is an easy and straightforward way of running requests or any other background tasks and calling web services using devices having latest OS virsion you must need to use AsyncTask.
It's also easy to implement e.g. onProgressUpdate if you need to show a progress bar of some sort while running your requests.
private class YourTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
//call your methods from here
//publish yor progress here..
publishProgress((int) ((i / (float) count) * 100));
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
//action after execution success or not
}
}

Identical code using httpurlconnection, work in java app But not andorid app. Why?

This works in a Java application run in Eclipse:
URL yahoo = new URL("http://www.nytimes.com/2011/08/17/business/global/merkel-arrives-in-paris-to-begin-economic-talks-with-sarkozy.html?_r=1&hp");
yc = (HttpURLConnection) yahoo.openConnection();
yc.setRequestProperty("User-Agent","sdfdfvjavasdvdsv");
in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
The same code doesn't work in an Android application in the same Eclipse +emulator:
public void onCreate(Bundle savedInstanceState) {
URL yahoo = new URL("http://www.nytimes.com/2011/08/17/business/global/merkel-arrives-in-paris-to-begin-economic-talks-with-sarkozy.html?_r=1&hp");
yc = (HttpURLConnection) yahoo.openConnection();
yc.setRequestProperty("User-Agent","sdfdfvjavasdvdsv");
in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
}
They are identical; one runs as a Java app, the other as an Android app. The Android app gets many redirects and eventually times out. Does the Android app send something special to tick off nytimes.com?
You should not (and, as of Honeycomb, cannot) do networking activity on the UI thread in Android, and onCreate executes on the UI thread. Check out the article on Painless Threading. Also check out the guide topic Designing for Responsiveness.
You are doing this in the main UI thread. The internet connectivity generally takes more time than the UI thread.
Try to do this in an Async Task class in the doInBackGround().
For more information refer to this. https://developer.android.com/reference/android/os/AsyncTask.html
In android you should use AsyncTask to achieve what you want.
An example of an AsyncTask would look sth like this:
private class FetchData extends AsyncTask<String, String, String>> {
ProgressDialog progress;
#Override
protected void onPreExecute() //Starts the progress dailog
{
progress = ProgressDialog.show(YourActivity.this, "Loading...",
"", true);
}
#Override
protected String doInBackground(String... strings)
{
String result="";
URL yahoo = new URL("http://www.nytimes.com/2011/08/17/business/global/merkel-arrives-in-paris-to-begin-economic-talks-
with-sarkozy.html?_r=1&hp");
yc = (HttpURLConnection) yahoo.openConnection();
yc.setRequestProperty("User-Agent","sdfdfvjavasdvdsv");
in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
//do sth with your data here
return result;
}
#Override
protected void onPostExecute(ArrayList<Article> result)
{
progress.dismiss();
}
}
Keep in mind that
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.
as stated on Android developers.
You can find more info about AsyncTask and how to implement it on the provided link.

Categories

Resources