This question already has answers here:
How can I fix 'android.os.NetworkOnMainThreadException'?
(66 answers)
Closed 9 years ago.
whoaa
i really need help, why my code result like that?
this is my code :
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(URL);
try{
HttpResponse response = httpClient.execute(httpPost);
String jsonResult = convertStreamToString((response.getEntity().getContent())).toString();
JSONObject obj = (JSONObject) new JSONTokener(jsonResult).nextValue();
JSONObject obj2 = obj.getJSONObject("GetRingkasObjekPajak_SingleResult");
String nameWP = obj2.getString("NM_WP");
TextView tv = (TextView)findViewById(R.id.dummy_text_three);
tv.setText(jsonResult);
}catch (MalformedURLException e) {
// URL is invalid
TextView tv = (TextView) findViewById(R.id.dummy_text_three);
tv.setText("url invalid");
} catch (SocketTimeoutException e) {
// data retrieval or connection timed out
TextView tv = (TextView) findViewById(R.id.dummy_text_three);
tv.setText("RTO");
} catch (IOException e) {
// could not read response body
// (could not create input stream)
TextView tv = (TextView) findViewById(R.id.dummy_text_three);
tv.setText("couldnt read response");
} catch (JSONException e) {
// response body is no valid JSON string
TextView tv = (TextView) findViewById(R.id.dummy_text_three);
tv.setText("json response fail");
}catch (Exception e) {
// TODO: handle exception
TextView tv = (TextView) findViewById(R.id.dummy_text_three);
tv.setText(e.toString());
}
i also have added internet permission
please help me
how to improve my code, so this problem solved.
Here is an example of Async task... Hope it will be helpfull to you.
private class YourAsyncTaskClass extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
//your http network call here.
return null;
}
#Override
protected void onPostExecute(String result) {
//update your ui here
}
#Override
protected void onPreExecute() {
//do any code before exec
}
#Override
protected void onProgressUpdate(Void... values) {
//If you want to update a progress bar ..do it here
}
}
Finally call this class from anywhere you want like..
new YourAsyncTaskClass().execute();
you can not perform network operations from main UI thread. you need to do networking related tasks in different thread. Better use AsyncTask
According to the doc
The exception that is thrown when an application attempts to perform a
networking operation on its main thread.
This is only thrown for applications targeting the Honeycomb SDK or
higher. Applications targeting earlier SDK versions are allowed to do
networking on their main event loop threads, but it's heavily
discouraged.
NetworkOnMainThreadException: The exception that is thrown when an application attempts to perform a networking operation on its main thread.
There is an article about Painless Threading on the Android developer site which is a good introduction to this, and will provide you with much better depth of answer than can be realistically provided here.
Run your code in AsyncTask.
You can learn about asyncTask here is best explanation with good example .
call your webservice inside aynctask.
private class NetworkTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
// call your network operation here
}
}
Related
I'm currently studying android on my own and pretty new to java. I'm wondering how AsyncTask works like this: onPreExecute() -> doInBackground() -> onPostExecute(). When I look at others define their AsynTask, it seems like only method is declared in their code with no calls upon the method. I can't figure out how doInBackground() comes after onPreExecute() with no code that links both like:
onPreExecute(){ ~~~~~ call doInBackground()}
My point is that when AsyncTask.execute() is called, onPreExecute() is called, then doInBackground(), finally onPostExecute(). I couldn't find any code in library that actually connects these together. All I could find is this:
#MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
#MainThread
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
Params... params) {
if (mStatus != Status.PENDING) {
switch (mStatus) {
case RUNNING:
throw new IllegalStateException("Cannot execute task:"
+ " the task is already running.");
case FINISHED:
throw new IllegalStateException("Cannot execute task:"
+ " the task has already been executed "
+ "(a task can be executed only once)");
}
}
mStatus = Status.RUNNING;
onPreExecute();
mWorker.mParams = params;
exec.execute(mFuture);
return this;
}
Here when AsyncTask.execute() is called, onPreExecute() is called. But without any connection to doInBackground the task works just fine. I feel like I'm missing some fundamental logic or process of java or android. Plz, help me with this unsolved question in mind. Sample code is shown below. Thank you in advance.
#Override
protected void onPreExecute() {
super.onPreExecute();
mLoadingIndicator.setVisibility(View.VISIBLE);
}
#Override
protected String[] doInBackground(String... params) {
/* If there's no zip code, there's nothing to look up. */
if (params.length == 0) {
return null;
}
String location = params[0];
URL weatherRequestUrl = NetworkUtils.buildUrl(location);
try {
String jsonWeatherResponse = NetworkUtils
.getResponseFromHttpUrl(weatherRequestUrl);
String[] simpleJsonWeatherData = OpenWeatherJsonUtils
.getSimpleWeatherStringsFromJson(MainActivity.this, jsonWeatherResponse);
return simpleJsonWeatherData;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(String[] weatherData) {
// COMPLETED (19) As soon as the data is finished loading, hide the loading indicator
mLoadingIndicator.setVisibility(View.INVISIBLE);
if (weatherData != null) {
// COMPLETED (11) If the weather data was not null, make sure the data view is visible
showWeatherDataView();
/*
* Iterate through the array and append the Strings to the TextView. The reason why we add
* the "\n\n\n" after the String is to give visual separation between each String in the
* TextView. Later, we'll learn about a better way to display lists of data.
*/
for (String weatherString : weatherData) {
mWeatherTextView.append((weatherString) + "\n\n\n");
}
} else {
// COMPLETED (10) If the weather data was null, show the error message
showErrorMessage();
}
I guess you shouldn't waste time on AsyncTask since it is deprecated.
Instead you should focus on coroutines, recommended by google here , or some other state of the art framework to achive what you want (e.g. rx java)
Yes, you are correct. The logic is onPreExecute() -> doInBackground() -> onPostExecute()
Synchronous VS asynchronous
You can read this article for a better understanding even though it's using Javascript to explain it.
ProgressDialog is showing only if I am sending text but when I sent images it gave me an error which tells that there are lot of activities running or the app can't handle all of it, the solution is to add StrictMode.ThreadPolicy before invoking those tasks but the problem is ProgressDialog is not showing anymore which is important to tell the user about the ongoing process.
I believe it is StrictMode.ThreadPolicy that causes the ProgressDialog to disappear. I am not using Asynctask that's why I haven't found solution on the Internet yet because most of them are using it. I am also planning to use Asynctask but my boss did not approve it, he's afraid that it will ruin the app.
{
private void upLoadImage(String path){
StrictMode.ThreadPolicy policy = new
StrictMode.ThreadPolicy.Builder().permitAll().penaltyDialog().build();
StrictMode.setThreadPolicy(policy);
uploadMedia(path);}}
{
private void uploadMedia(String path) {
String ImageName = "image_name";
String ImagePath = "image_path";
try {
String charset = "UTF-8";
File uploadFile1 = new File(path);
String requestURL= "http://myurl";
MultipartUtility multipart = new MultipartUtility(requestURL,
charset);
multipart.addFormField(ImageName, "iName");
multipart.addFormField(ImagePath, "iPath");
multipart.addFilePart("uploadedfile", uploadFile1);
List<String> response = multipart.finish();
Log.v("rht", "SERVER REPLIED:");
for (String line : response) {
Log.v("rht", "Line : "+line);
if(line=="true"||line=="Saved"){
progressDialog.dismiss();
}
}
// Toast.makeText(this, ""+response, Toast.LENGTH_SHORT).show();
finish();
} catch (Exception e) {
e.printStackTrace();
}
}
}
if you access Network in UI thread the error is shown.You cannot do the network operations in the main thread.It is better to use a worker thread or ayntask. But if you are willing to accept the consequences, and must do network operations on the main thread, you can override the default behavior:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
I've just gotten into android development, and while trying to create a login form i ran into some problems.
What I want to do is enter username and password and press login, when the login button is pushed I want it to do a JSON request with the account information to my server and get a response with whether or not the user is allowed to log in. If the user is allowed, I want to change to a new view.
My code receives the JSON information correctly, but from what I've understood the UI-code (pushing a new activity) should be done in onPostExecute(). My problem is that onPostExecute is never run, I've looked at other ppl with the same problem, but their solutions hasn't worked for me. What they have said is that i need to have an #Override before onPostExecute, but when I add that i get the compilation error that "the method does not override method from its superclass".
I've read solutions from people having that problem as well, and from what I have read the problem is that the method onPostExecute has to have the same parameters as the result parameter from doInBackground(). My problem is that I feel I already do, and when I try to look in what the superclass has (that is AsyncTask.java) it says that the method onPostExecute() looks like:
protected void onPostExecute(Result result) {
}
But I have no idea what class Result belongs to..
networkingTask is run using this line:
new networkingTask().execute(url);
If anyone could help me I'd be eternally grateful! :)
This is what my code looks like
private class networkingTask extends AsyncTask {
Context context;
private networkingTask(Context context) {
this.context = context.getApplicationContext();
}
public networkingTask() {
}
#Override
protected JSONObject doInBackground(Object... params) {
try {
String urlString = (String) params[0];
System.out.println(urlString);
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
// getting JSON string from URL
JSONObject json;
json = jParser.getJSONFromUrl(urlString);
String responseLogged = json.getString("logged");
System.out.println("can we log in?: "+ responseLogged);
return json;
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(JSONObject result) {
String responseLogged = "";
try {
responseLogged = result.getString("logged");
} catch (JSONException e) {
e.printStackTrace();
}
if(responseLogged.equals("true")){ //Login = true
Intent intent = new Intent(context, ShowListActivity.class);
intent.putExtra(EXTRA_JSON_OBJECT, result.toString());
startActivity(intent);
} else{ //Login = false
System.out.println("wrong password");
}
return;
}
}
In your line:
private class networkingTask extends AsyncTask
just change it to:
private class networkingTask extends AsyncTask<String, Void, JSONObject>
while String is the place for you to pass in the parameters, in your case it is url, the second parameter Void is for showing progress and the last one is the processed result to be passed from doInBackground to onPostExecute
For further explanation & info, please refer to Android Developers: AsyncTask
I think you may need to fill out the generic types for your AsyncTask. See the "Usage" section in the AsyncTask documentation.
Your class signature should look something like this:
private class networkingTask extends AsyncTask<Object, Void, JSONObject>
The types in the brackets here correspond to the argument types for doInBackground, onProgressUpdate, and onPostExecute, respectively, and are necessary if you're going to override these methods such that they are different from the generic method signatures.
Also, as a side note, it's a common convention in Java/Android to use upper CamelCase to start a class name. I'd also change the name of your class to "NetworkingTask" to help other developers looking at your code to better understand it.
The signatures don't match. You're attempting to override:
protected void onPostExecute(Result result)
with the signature
protected void onPostExecute(JSONObject result)
...which doesn't exist in the superclass.
I am using this article to help me send automated emails, but I am having an issue in which nothing seems to be happening and no errors are generated.
I used AsyncTask but it is not sending the mail at all.
public class Sender extends AsyncTask< Void, Void, Void> {
private Exception exception;
protected Void doInBackground(String... arg0) {
Log.v("aws", "OPEN asa");
Mail m = new Mail("email#email.com", "password");
String[] toArr = {"to#mail.com"};
m.setTo(toArr);
m.setFrom("from#gmail.com");
m.setSubject("This is an email sent using my Mail JavaMail wrapper from an >Android device.");
m.setBody("Email body.");
try {
//m.addAttachment("/sdcard/filelocation");
if(m.send()) {
Log.v("aws", "OK SENT");
} else {
Log.v("aws", "NOT SENT");
}
} catch(Exception e) {
Log.v("aws", "EXCEPTION . NOT SENT");
}
return null;
}
#Override
protected Void doInBackground(Void... arg0) {
// TODO Auto-generated method stub
return null;
}
protected void onPostExecute(Void... arg0) {
// TODO: check this.exception
// TODO: do something with the feed
}
}
I have used new Sender().execute(); to execute the task, but nothing is happening and no errors are being thrown.
What am I doing wrong?
EDIT
Code has two doInBackground such that second overridden my working doInBackground
Be careful, you have two doInBackground() methods in your code, and the #Override version is what gets executed by the AsyncTask. Just move the code from the wrong doInBackground() version to the right one and delete the wrong one.
I'm trying to learn Java right now and I've jumped in the deep end by starting with the Android Faceobok API. Right now, I'm trying to get some information from my graph data (a friend in this case) and display it in a text view. This seems rather trivial but it has been anything but.
JSONObject json_data = null;
try
{
JSONObject response = Util.parseJson(facebook.request("/me/friends", mBundle, "GET")); // Get a friend information from facebook
JSONArray jArray = response.getJSONArray("data");
json_data = jArray.getJSONObject(0);
String name = json_data.getString("name");
mText.setText(name);
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
catch (JSONException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
catch (FacebookError e)
{
e.printStackTrace();
}
The TextView doesn't change when I do this and I'm not exactly sure where I've gone wrong.
As an aside, there is a shortage of good Android Facebook API tutorials out there. Most are hundreds of lines of code; I don't have the energy or patience to consume all of that.
I have a feeling your initial request isnt working properly. you should try this line instead:
JSONObject response = Util.parseJson(facebook.request("me/friends"));
Firstly I think in your initial request, it should be "me/friends" rather than "/me/friends". Secondly you dont necessarily need the mBundleor "GET" parameters in what you're trying to achieve. Have you even defined parameters in mBundle? You're also getting information from the request method, so the "GET" parameter isn't necessary.
Try the line i just wrote, as it is simpler and will get your friends information. The rest of your code is fine.
Your assertion about being "trivial" is essentially true, but generally speaking "jumping into the deep end" rarely results in anything other than a drowning.
I'm going to be "that guy" and recommend you actually get to the point of having a general understanding and minimal competency in Java before tackling someone else's API. Once you know how Java works - the "PME" ... properties, methods, and events - learning anyone's API becomes just a question of following the proper steps.
Besides that little bit of PS, answer the following:
1) received data from your source?
2) what thread are you invoking this on?
3) any of the objects null?
4) any exceptions being thrown when you look in the Console or Log (print those out to the Log versus your current implementation)?
And, not for nothing, but if you don't have the time or patience to learn the "how's and why's" of an API or software dev in general then this will be a long exercise for you if the work ever becomes non-trivial.
Just one man's opinion who also has attempted to drink from fire hose before.
Update: Here's all of my code:
public class FriendsActivity extends Activity {
/** Called when the activity is first created. */
Facebook facebook = new Facebook("194653157245506");
TextView mText;
Bundle mBundle;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mText = (TextView) this.findViewById(R.id.text);
facebook.authorize(this, new String[] {"offline_access", "user_interests", "friends_interests"},
new DialogListener() {
#Override
public void onComplete(Bundle values) {}
#Override
public void onFacebookError(FacebookError error) {}
#Override
public void onError(DialogError e) {}
#Override
public void onCancel() {}
});
JSONObject json_data = null;
try
{
JSONObject response = Util.parseJson(facebook.request("/me/friends", mBundle, "GET")); // Get a friend information from facebook
JSONArray jArray = response.getJSONArray("data");
json_data = jArray.getJSONObject(0);
String name = json_data.getString("name");
Log.i("friend is", name);
mText.setText(name);
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
catch (JSONException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
catch (FacebookError e)
{
e.printStackTrace();
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
facebook.authorizeCallback(requestCode, resultCode, data);
}
}
I may be a little off key. but I have done facebook api development in C#, and i am wondering if you have had the client login.
Facebook works with OAuth to allow you to authorize through them for a client. (Even your own account as the client) therefore you may need to login.
Another thing to look at is, do you have the TextView that is in the Activity that is being displayed..
Try putting in a breakpoint and looking over the code as it is executing, Debug View is great for that.
see if your response is being populated.
make sure you have the Text from the Activity.
mText = (TextView)findViewById(R.id.TextView1); //or whatever you named it.
Also the LogCat should show you the stack trace for any errors that occur, maybe posting some of the output would help