I have two Android mobile devices one v2.3 api 9 and one v3.1 honeycomb
I want to post an http api link for sms code. It turns that i got an error in honeycomb and the other mobile works fine this is the code
public void sendSMS(String phone_num, int password)
{
try
{
HttpClient hc = new DefaultHttpClient();
HttpPost post = new HttpPost("http://www.google.com/");
hc.execute(post); // I got an error here
}
catch(IOException e)
{
Log.e("error", "error");
}
}
StrictMode is enabled in HoneyComb, you must disable it to avoid NetworkOnMainThreadException
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
but that´s not recommended, use Asynctask, here you can find an example:
http://developer.android.com/reference/android/os/AsyncTask.html
You're experiencing this because of a new feature in Android Honeycomb. If you look through your logs you will see you are getting a NetworkOnMainThreadException Exception
In Android Honeycomb there is a new application policy that restricts the execution of time consuming calls on the main thread.
Please check your exception stack if you see the following: StrictMode$AndroidBlockGuardPolicy.onNetwork
What helped me was to read this and then fix my code to not use the main execution thread for the HTTP call.
100% working solution!
Place the following codes above your super.onCreate under protected void onCreate method:
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Idea from Jorgesys! Thanks to him! Hope it solves your problem~
I had the same problem and cleared using Async Task.So dont call httppost request in main thread Instead use Async task to do http post.It also gives you more comfortable .link:http://www.vogella.com/articles/AndroidPerformance/article.html
Related
I need to make an api call on click of button. So i do it following way.
btn.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
try
{
HttpResponse apiResponse = mySingleTonehttpClient.execute(new HttpGet(Url));
HttpEntity resEntity = apiResponse.getEntity();
InputStream instream = resEntity.getContent();
String result = convertInputStreamToString(instream);
}
}
This code is working fine if i set targetSDKVersion = 8 in Manifest file. But giving me Network mainthread error for targetSDKVersion = 11. Can anyone suggest me what should i do?
Thanks,
Jay
The reason for this is that you're not supposed to do things that can possible take a long time in the UI Thread. Because doing that will result in the UI being blocked, and you're application will be lagging.
That's why you should either use a Worker Thread or an AsyncTask to do Network IO. You can read more information about how to use them and how they can interact with the UI Thread on the Android Developer guide.
You should not do networks call on main/UI thread of Application. you may start new worker thread that will run in separate thread rather than on UI thread.
I'm attempting to allow a user to login via a WebView within a DialogPreference my application and this work fine, but I seem to be stuck on how to do this properly.
If I do this as next, I get an error
Error
Caused by: android.os.NetworkOnMainThreadException
E/AndroidRuntime(732): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
Code
#Override
protected void onBindDialogView(View v) {
super.onBindDialogView(v);
this.webViewOauth = (WebView) v.findViewById(R.id.web_oauth);
try {
String authURL = this.backend.getRequestToken().getAuthenticationURL();
webViewOauth.loadUrl(authURL);
}
catch (TwitterException e) {
e.printStackTrace();
}
}
I can fix this by changing the ThreadPolicy, but as far as I can tell, there is a reason for this restriction
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
So, I switched this to an AsyncTask and I get a warning
Warning
java.lang.Throwable: Warning: A WebView method was called on thread
'AsyncTask #4'. All WebView methods must be called on the UI thread.
Future versions of WebView may not support use on other threads.
Code
#Override
protected void onBindDialogView(View v) {
super.onBindDialogView(v);
MyLoginTask login = new MyLoginTask(this, v, this.backend);
login.execute();
}
Both methods work, but is there a specific way to do this properly? The ThreadPolicy seems to be a hack and could cause it to block the UI thread, but I'n not sure if it actually will, while the AsyncTask method clearly is incorrect too based on the warning.
Is this an appropriate time to set the ThreadPolicy since it actually is running a UI element?
Yes, using the ScrictMode Policy is a hack, and a terrible one as stated here and here
You have two ways to solve this:
1- Return the authURL from the onPostExecute() method of your MyLoginTask. Simply define a setter in the object that calls the MyLoginTask, and have onPostExecute() assign the result to it.
2- Pass a reference to your webview to the MyLoginTask, and have it load the url in the onPostExecute(). Because onPostExecute() will always run in the UI thread, you will get rid of the warning.
In any case, do check out this post by the Android developers about 'Painless Threading'; you will certainly find it helpful: http://android-developers.blogspot.ca/2009/05/painless-threading.html
Fairly new to Android and created/tested my app using Android 2.3.5 (Gingerbread). I have multiple database connections I used HTTP Post (but did not use AsyncTask) and everything worked great. I then tested it on Android 4.0.3 (Ice Cream Sandwhich) and I'm not able to connect to the database, therefore my app does not work.
Wondering what do I need to consider to allow this working app to run on Ice Cream Sandwhich? I did move the database connection out of the UI Thread (but not AsyncTask) and it still does not connect.
Here is my class I created outside of my UI Thread:
public class InputsRecapGetTask {
public InputsRecapGetTask(InputsRecap activity,
ProgressDialog progressDialog) {
this.activity = activity;
this.progressDialog = progressDialog;
getDatabase();
}
public void getDatabase() {
// TODO Auto-generated method stub
progressDialog.show();
// create new default httpClient
HttpClient httpclient = new DefaultHttpClient();
// create new http post with url to php file as pararmenter
HttpPost httppost = new HttpPost(
"http://test.com/returnBBD.php");
// assign input text to strings
user = Login.userStatic;
Did you examine the logs? IIRC, Android 4 requires that http requests are not done from the main thread. There must be a message telling this.
On the other hand, please keep in mind that
if you turn the screen, the Activity that created the AsyncTask may
be removed from the screen (forever) and replaced by another
Activity; it (the 1st Activity) will receive the result, but will not show anything;
in Android 4, all AsyncTasks are by default serviced by a single
thread; this guarantees that responses arrive in the order the
requests are made, but also means that the 2nd request will start only after the
1st one finishes (or times out).
According to MVC, the data retrieval must be done by the model, not by the controller (Activity) whose lifetime is that of a View.
I'm trying to post data to URL by using Android App.
URL:
parameters:
"name" and "message"
I use the following code but it doesn't work:
public void onClick(View v) {
// Create a new HttpClient and Post Header
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://comparch2011.appspot.com/");
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("name", "DEV"));
nameValuePairs.add(new BasicNameValuePair("message", "AndDev is Cool!"));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
}
-first thing first : you should use adb logcat. It will give you real time logs of your phone on your computers, it is incredibly useful to know what is going on.
-I suspect that you are making these calls in an Activity and in this case the app is simply crashing because of that : their is a safeguard to prevent you from doing that. It raises errors 'network on main thread' when necessary (like here).
The problem is that Activities are ran on the main thread, the one that is also used for the UI. so when you make such a network call, all the UI is blocked until the function has returned (and since it is waiting for the website to respond it can take a couple of seconds, which is very bad for the usability of your app).
The solution is to use an AsyncTask . It is an easy to use class that will allow you to make asynchronous calls (ie calls that don't block the UI).
As you can see in your LogCat, the error is a NetworkOnMainThreadException.
Which Android states here http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html as:
NetworkOnMainThreadException:
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.
So take a look at http://developer.android.com/reference/android/os/AsyncTask.html instead, and be aware that the getResponse not should be called on the UI thread.
Alternatively you can probably just change the target or change the strictpolicy as follows, but I would no suggest doing so...
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
You shouldn't perform Network activities on the main thread. Because it doesn't allow the user to respond to the view when the network action is being performed.
Use an Asynctask, and it will work.
http://developer.android.com/reference/android/os/AsyncTask.html
Nithin
I have some code below:
protected void testConnection(String url) {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url);
ResponseHandler<String> responsehandler = new BasicResponseHandler();
try {
String connection = httpclient.execute(httpget, responsehandler);
Toast.makeText(getBaseContext(), R.string.connection_succeed, Toast.LENGTH_SHORT).show();
view_result.setText(connection);
} catch(IOException e) {
Toast.makeText(getBaseContext(), R.string.connection_failed, Toast.LENGTH_SHORT).show();
}
httpclient.getConnectionManager().shutdown();
}
and add a permission in Menifest:
<uses-permission android:name="android.permission.INTERNET"/>
But it goes an exception:
NetworkOnMainThreadException,
How can i do?
On ICS and later you cannot do network operations on the UI thread anymore. Instead you are forced to create a new thread and do your networking stuff there.
Possible tools are Android's AsyncTask and the normal Java Thread.
A good tutorial can be found here: Android Threads, Handlers and AsyncTask - Tutorial
Starting from API 11, you can not manipulate network (time-consuming) operations on main thread. Use AsyncTask or Thread to perform such operations.
You cant perform network operations in event thread, since android Api Level 11.
Instead you should do network operation in another thread than event thread, and use Handler or Asynctask to do so.
I you run your code in android 2.x and its lower version, i think this code will run perfectly. But if you run this in 3.x and it's upper version then you get an Exception. The problem is the you need to call the web service from your worker thread(AsyncTask<>) . You can not call the web service from the main thread.