I coded a class which starts a http connection for getting the text of e.g. website.
I used AsyncTask but I got NetworkOnMainException. May u help me?
The class
public class getXMLData extends AsyncTask<String, Void, String> {
TextView _textview;
public getXMLData(TextView textview) {
_textview = textview;
}
protected String doInBackground(String... url)
{
String _text = "";
try {
try {
URL _url = new URL(url[0]);
HttpURLConnection con = (HttpURLConnection) _url.openConnection();
_text = readStream(con.getInputStream());
}
catch (Exception e) {
e.printStackTrace();
}
}
catch (Exception e) {
e.printStackTrace();
}
return _text;
}
protected void onPostExecute(String result)
{
_textview.setText(result.toCharArray(), 0, result.length());
}
private String readStream(java.io.InputStream in) {
java.io.BufferedReader reader = null;
String result = "";
reader = new BufferedReader(new InputStreamReader(in));
try {
while ((reader.readLine() != null)) {
result = result + reader.readLine();
}
}
catch (java.io.IOException i)
{
}
finally
{
try {
reader.close();
}
catch (java.io.IOException e) {
e.printStackTrace();
}
}
return result;
}
Here how I start the AsyncTask:
bu_aktualize.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
_getXMLData.doInBackground("http://www.google.de");
}
});
Thanks for your help.
You do not call doInBackground() yourself. Instead, you call execute() or executeOnExecutor() to start the AsyncTask.
You may wish to review the documentation for AsyncTask, which shows an example of setting up an AsyncTask, including a call to execute().
Related
I'm trying to download an image from a URL by creating a Bitmap using
bitmapFactory.decodeStream(InputStream) and then imageView.setImageBitmap(bitmap) but I am always getting this error:
D/skia: --- Failed to create image decoder with message
'unimplemented'. package com.example.flickrapp;
Here is my code:
import statements will go here ...
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onStart() {
super.onStart();
Button b = (Button)findViewById(R.id.getanimage);
b.setOnClickListener(new GetImageOnClickListener() {
#Override
public void onClick(View v) {
super.onClick(v);
}
});
}
public class GetImageOnClickListener implements View.OnClickListener {
#Override
public void onClick(View v) {
AsyncFlickrJSONData imagesData = new AsyncFlickrJSONData();
imagesData.execute("https://www.flickr.com/services/feeds/photos_public.gne?tags=trees&format=json");
}
}
public class AsyncFlickrJSONData extends AsyncTask<String, Void, JSONObject> {
#Override
protected JSONObject doInBackground(String... strings) {
String flickrUrl = strings[0];
JSONObject jsonFlickr = null;
URL url = null;
try {
url = new URL(flickrUrl);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
String s1 = readStream(in);
int lengthS = s1.length();
String s = (String) s1.subSequence(15, lengthS-1);
jsonFlickr = new JSONObject(s);
} finally {
urlConnection.disconnect();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException | JSONException e) {
e.printStackTrace();
}
return jsonFlickr;
}
#Override
protected void onPostExecute(JSONObject jsonFlickr) {
super.onPostExecute(jsonFlickr);
try {
String firstUrl = jsonFlickr.getJSONArray("items").getJSONObject(0).getString("link");
AsyncBitmapDownloader firstAsyncImage = new AsyncBitmapDownloader();
firstAsyncImage.execute(firstUrl);
Log.i("JFL", firstUrl);
} catch (JSONException e) {
e.printStackTrace();
}
}
private String readStream(InputStream in) {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
Log.e(TAG, "IOException", e);
} finally {
try {
in.close();
} catch (IOException e) {
Log.e(TAG, "IOException", e);
}
}
return sb.toString();
}
}
public class AsyncBitmapDownloader extends AsyncTask<String, Void, Bitmap> {
ImageView firstImage = (ImageView) findViewById(R.id.image);
#Override
protected Bitmap doInBackground(String... strings) {
String imageUrl = strings[0];
Bitmap bm = null;
URL url = null;
try {
url = new URL(imageUrl);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
bm = BitmapFactory.decodeStream(in);
} finally {
urlConnection.disconnect();
}
} catch(IOException e){
e.printStackTrace();
}
return bm;
}
#Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
firstImage.setImageBitmap(bitmap);
}
}
}
Any Suggestions or Ideas are welcomed :)
i want to get the result form AsyncTask , i can show with system.out.println(), but i want keep that result and save on a new attribute, outside from AsyncTask;
OnTaskFinished.java
public interface OnTaskFinished
{
public void onFeedRetrieved(String feeds);
}
RetrieveFeedTask.java
class RetrieveFeedTask extends AsyncTask<String, Void, String>
{
String HTML_response= "";
String VideoLink;
public String getVideoLink() {
return VideoLink;
}
public void setVideoLink(String videoLink) {
this.VideoLink = videoLink;
}
OnTaskFinished onOurTaskFinished;
public RetrieveFeedTask(OnTaskFinished onTaskFinished)
{
onOurTaskFinished = onTaskFinished;
}
#Override
protected void onPreExecute()
{
super.onPreExecute();
}
#Override
protected String doInBackground(String... urls)
{
try
{
URL url = new URL(urls[0]); // enter your url here which to download
URLConnection conn = url.openConnection();
// open the stream and put it into BufferedReader
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
while ((inputLine = br.readLine()) != null)
{
//System.out.println(inputLine);
if(inputLine.toString().contains("<meta property='og:image'"))
{
String str =inputLine;
str = str.replace("<meta property='og:image' content=\"", "");
//System.out.println(str);
VideoLink=str;
setVideoLink(str);
inputLine=str;
}
HTML_response += inputLine;
}
br.close();
//System.out.println("Done");
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
return VideoLink;
}
#Override
protected void onPostExecute(String feed)
{
onOurTaskFinished.onFeedRetrieved(feed);
}
}
and here is how i call
Main.java
String data;
....
new RetrieveFeedTask(new OnTaskFinished()
{
#Override
public void onFeedRetrieved(String feeds)
{
System.out.println(feeds);
}
}).execute(VideoUrl);
i want that feeds get out and set on a diferente value outside from RetrieveFeedTask
on this case set the result on data;
this is the class for reading json string from web
{
public class JSONmethod extends AsyncTask<String,String,String>
{
public String result_string;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
BufferedReader reader = null;
HttpURLConnection connection = null;
StringBuffer buffer;
try {
URL url;
url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
String line= "";
buffer = new StringBuffer();
while ((line = reader.readLine())!= null)
{
buffer.append(line);
}
return buffer.toString();
}
catch(MalformedURLException e)
{
e.printStackTrace();
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
result_string=result;
}
public String result_string_josn()
{
return result_string;
}
}
method "result_string_json()" return null string
i want to use this class frequntly for reading the json string from the web
so i made this method for return string which will returns from onPostExecute
this is the class where i want that value which is generate in post execute through method or anything else
simple.java
package com.bhatti.bis;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
public class simple extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple);
JSONmethod j = new JSONmethod();
j.execute("here is json string");
Toast.makeText(this,j.result_string_josn(),Toast.LENGTH_LONG).show();
}
}
Use EventBus library. It's very easy to use and will perfectly fix your problem:
First create a simple class for your Event:
public class MyEvent{
private String data;
public MyEvent(String data) {
this.data = data;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
Then in your Activity or wherever, register and unregister the EventBus, as explained in the docs.
Now post the appropriate event:
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
EventBus.getDefault().post(new MyEvent(jsonArray.toString()));
}
All that's left for you to do is to listen for that event wherever you want (in another Activity, Fragment, Service - that's what makes EventBus great):
#Subscribe
public void onMyEvent(MyEvent myEvent){
String data = myEvent.getData();
//do whatever you wish with the text (e.g. make a toast, write it somewhere)
}
Async Task is asynchronous task, please read https://en.wikipedia.org/wiki/Asynchrony_%28computer_programming%29
Remove Toast just after :
JSONmethod j = new JSONmethod();
j.execute("here is json string");
And put it in onPostExecute :
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Toast.makeText(this,result,Toast.LENGTH_LONG).show();
}
Android handles input events/tasks with a single User Interface (UI) thread and the thread is called Main thread. Main thread cannot handle concurrent operations as it handles only one event/operation at a time.For detail read this tutorials
JSONmethod jSONmethod = new JSONmethod();
jSONmethod.execute("Your json string");
public class JSONmethod extends AsyncTask<String,String,String>
{
public String result_string;
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
BufferedReader reader = null;
HttpURLConnection connection = null;
StringBuffer buffer;
try {
URL url;
url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
String line= "";
buffer = new StringBuffer();
while ((line = reader.readLine())!= null)
{
buffer.append(line);
}
return buffer.toString();
}
catch(MalformedURLException e)
{
e.printStackTrace();
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.d("JSONmethod","result = "+result);
}
}
Other class:
SpotifyTask st = new SpotifyTask(new Closure<JSONObject>() {
#Override
public void executeOnSuccess(JSONObject result) {
track.setJson(result);
}
});
st.execute("asd");
Being SpotifyTask:
public class SpotifyTask extends AsyncTask<Object, Void, JSONObject> {
private final Closure<JSONObject> closure;
public SpotifyTask(Closure<JSONObject> closure) {
this.closure = closure;
}
public static void getTrack(Closure<JSONObject> closure) {
new SpotifyTask(closure).execute("asd");
}
#Override
protected JSONObject doInBackground(Object... params) {
JSONObject result = null;
SpotifyCall spcall = new SpotifyCall();
try {
result = spcall.getTrack();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return result;
}
#Override
protected void onPostExecute(JSONObject result) {
System.out.println("ASD: on post execute "+result);
closure.executeOnSuccess(result);
}
}
So... doInBackground is running OK, and and returning a JSONObject all right; I know because Im debbuging it and "result" IS a JSONObject.
But onPostExecute is never executed, the debugger never gets there and "ASD: on postexecute "+result is never logged.
Any suggestions?
Thanks in advance!
The problem was that I was "holding" the UI Thread:
this.status = "loading";
final Track track = new Track();
SpotifyTask.getTrack(new Closure<JSONObject>() {
#Override
public void executeOnSuccess(JSONObject result) {
track.setJson(result);
}
});
while (this.status.equals("loading")) {
if (track.getJson() != null) {
this.trackUno = track.getJson();
this.status = "ready";
} else {
try {
System.out.println("Not ready, waiting.");
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
As soon I removed the while block, it worked perfectly.
I would have to find another way to "wait" for the call to be complete.
Thanks for your time fellas!
Basically the idea is I check to see if the web session is still valid, if not I start the main activity which logs the user in automatically.
I have this working, not sure if it's the best way to do it. If anyone has a better way please let me know.
Thanks
Useage:
#Override
public void onResume() {
super.onResume();
new LoginCheck(this,new Intent(this,MyActivity.class));
}
The Class
public class LoginCheck extends Application {
Intent home;
Activity activity;
public LoginCheck(Activity activity, Intent home) {
this.activity = activity;
this.home = home;
new Check().execute();
}
public class Check extends AsyncTask {
#Override
protected Object doInBackground(Object... objects) {
try {
InputStream is = null;
String result = "";
JSONObject jArray = null;
PersistentCookieStore myCookieStore = new PersistentCookieStore(MyApp.getAppContext());
//http post
DefaultHttpClient mClient = AppSettings.getClient();
try {
HttpPost request = new HttpPost(MyApp.getServiceUrl() + "/Api/Login/AmILoggedIn");
mClient.setCookieStore(myCookieStore);
HttpResponse response = mClient.execute(request);
HttpEntity entity = response.getEntity();
is = entity.getContent();
} catch (Exception e) {
Log.e("log_tag", "Error in http connection " + e.toString());
}
//convert response to string
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result = sb.toString();
} catch (Exception e) {
Log.e("log_tag", "Error converting result " + e.toString());
}
final String r = result;
final Intent i = home;
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
try {
JSONObject j = new JSONObject(r);
if (!j.getBoolean("Success")) {
try {
activity.startActivity(i);
} catch (Exception e) {
Log.e("log_tag", e.getMessage());
}
}
} catch (JSONException e) {
Log.e("log_tag", "Error parsing data " + e.toString());
}
}
});
return true;
} catch (Exception e) {
}
return null;
}
}
}
Here is the cleaned up version
Use:
new LoginCheck() {
#Override
public void LoggedIn() {
//To change body of implemented methods use File | Settings | File Templates.
}
#Override
public void LoggedOut() {
//To change body of implemented methods use File | Settings | File Templates.
}
};
Class
public abstract class LoginCheck {
public LoginCheck(){
new Check().execute(true);
}
public class Check extends AsyncTask<Boolean,Boolean,Boolean>{
#Override
protected Boolean doInBackground(Boolean... objects) {
JSONStringer jsonSend = null;
try {
jsonSend = new JSONStringer()
.object()
.endObject();
} catch (JSONException e) {
Log.e("log_tag", "Error creating Json " + e.toString());
}
JSONObject result = JsonPost.postJSONtoURL(MyApp.getServiceUrl() + "/Api/Login/AmILoggedIn", jsonSend);
try {
if (result.getBoolean("Success")) {
return true;
}
} catch (JSONException e) {
Log.e("log_tag", "Error parsing data " + e.toString());
}
try {
if (!result.getBoolean("Success")) {
return false;
}
} catch (JSONException e) {
Log.e("log_tag", "Error parsing data " + e.toString());
}
return false;
}
#Override
protected void onPostExecute(Boolean result){
if(result)
LoggedIn();
if(!result)
LoggedOut();
}
}
public abstract void LoggedIn();
public abstract void LoggedOut();
}