My android app keeps on crashing.
I'm trying to connect to a webservice via post call.
But my app keeps on crashing every time it tries to call the webservice.
import android.app.Activity;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import java.io.IOException;
public class PostActivity extends Activity {
//static String response = null;
public void loadPost() throws IOException {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpEntity httpEntity = null;
HttpResponse httpResponse = null;
String blogFeedUrl = "http://localhost/medapp/public/mobile/post";
HttpGet httpGet = new HttpGet(blogFeedUrl);
httpResponse = httpClient.execute(httpGet); // <-- this is where the application crashes
}
}
From the code you have posted and related imports in the same, depending on the O.S(Esp Honeycomb and onwards), your application would crash due to the NetworkOnMainThreadException. You are attempting the network operation on the main thread, not in a background thread or Asyctask.
In your logcat(if you post that it'l help), NetworkOnMainThreadException will be thrown:
E/AndroidRuntime(673): java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.example/com.example.ExampleActivity}: android.os.NetworkOnMainThreadException
The explanation as to why this occurs is well documented on the Android developer's site:
A NetworkOnMainThreadException 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.
Go through:
Why the app would crash or work depending on O.S.
Try AsyncTask to avoid NetworkOnMainThread
Why should you not use the Strict Mode alternative as your solution and only to debug(i'd suggest avoid that also actually, you know what is the problem now):
Critical to fix it, not by setting Thread policies
Related
This question already has answers here:
How can I fix 'android.os.NetworkOnMainThreadException'?
(66 answers)
Closed 7 years ago.
I want to develop an app that allows me to upload data from form of an android app as a text file in server
here is the mainactivity class
package com.example.incrediblemachine.sendtest;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends Activity {
EditText msgTextField;
Button sendButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//make message text field object
msgTextField = (EditText) findViewById(R.id.msgTextField);
//make button object
sendButton = (Button) findViewById(R.id.sendButton);
}
public void send(View v)
{
//get message from message box
String msg = msgTextField.getText().toString();
//check whether the msg empty or not
if(msg.length()>0) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://ramsproject.16mb.com/sendorder.php");
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("id", "01"));
nameValuePairs.add(new BasicNameValuePair("message", msg));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
httpclient.execute(httppost);
msgTextField.setText(""); //reset the message text field
Toast.makeText(getBaseContext(),"Sent",Toast.LENGTH_SHORT).show();
}catch (IllegalStateException e)
{
e.printStackTrace();
}
catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} else {
//display message if text field is empty
Toast.makeText(getBaseContext(),"All fields are required",Toast.LENGTH_SHORT).show();
}
}
}
It comes up with an exception at line 53
httpclient.execute(httppost);
the exception says android.app.NetworkOnMainThreadException
How do i solve this
Just use a thread.
Thread thread = new Thread(new Runnable(){
#Override
public void run() {
try {
//Your code goes here
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
call the httpClient in this thread.
You can't do your network calls in your MainThread. You should use an asynctask for your network operations. You can find more information about it from the link below:
https://developer.android.com/reference/android/os/AsyncTask.html
Also i recommand you to use a network library to handle your network operations. You can find a good library for your network operations from the link below:
http://square.github.io/retrofit/
This exception that is thrown when an application attempts to perform a networking operation on its main thread.
Applications targeting the Honeycomb SDK or higher are allowed to do networking on their main event loop threads to avoide sluggishness on unresponsive situatons related to networs. you can reffer to Documentation.
To resolve this you have options like :
1.Using AsyncTasks
2. Threads
3. Handlers
I would like to provide a solution for you here. For this i would like to point few points before you understand the solution.
All android components(Activity,Service,BroadcastReceiver,Fragment and anything that visually shows data) run in the UI Thread or Main Thread, to understand this read further.
Every Android Application run on its own process and have a unique userID for it. When ever an android application is installed it is given a unique user ID. Whenever the application runs it is given a separate Memory space and path for program execution. This process consists of its own memory called Heap. The process is like a separate environment given to your application to run code or process code.
A thread on the other hand is a sub process or lightweight process. It is spawned inside the process. When ever a thread is created it is given some part of memory (stack). A process can spawn many number of threads.
A thread can not access another threads memory (stack) , it is private to the particular thread. But they can access the Process memory (heap memory). Think heap memory as a global memory.
Whenever a process is created for your application a single thread is created, which is mandatory. This thread is called a main thread. In android it maybe also referred as UI thread. Because this threads processes all the UI components that you see(Like activity,Fragment and Services(even though service is run on the background, it is run on UI Thread), etc).
Android framework is created in such a way that they wanted to handle all the UI operations on the Main thread giving it high priority to process UI components. Because the UI is the one shown to the user and the user will not like an application if it is frozen without processing the UI.
This is the reason you get a "NetworkOnMainThread" exception. Because Android restricts running long running operations like network access, file access, database access and those processings run on the UI Thread. Because it will take much time to process restricting the UI to be responsive, as it doesn't give an opportunity for the UI components to process.
I hope you understand why you get such exceptions now. Long running operations should not restrict UI thread operation. so it should be moved from UI thread to another new thread(Move the code where you create a HttpClient until you receive a response from it). Android also offers another alternative for this. You can create an AsyncTask, which handles the thread creation process for you. You can just write you code and pass the result to the UI thread. Learn more about it.
Notes: All threads access the process memory. But a process cannot access another process's memory unless it has the same USER ID. Means unless it is from one of your application. This can be done using AIDL interface.
I hope this solution helped you to understand the exception you get and solve them.
I need a bit of help phrased in easy to understand terms. I've tried asking this question on multiple forums, but keep getting answers back that assume some knowledge even though I specified that I have only rudimentary skills in Android building and Java.
The user Skynet was very helpful when I asked my initial question here, but the research he/she prompted me to do proved difficult to follow up on.
https://stackoverflow.com/questions/28403243/how-to-make-an-app-that-syncs-via-internet
I want to make an app with a textview that updates via internet everytime the user open the app.
What is the best way to do this? And what would I have to do to do it?
Thank you in advance!
To get an idea of how new to this I am, here's an app I've published: https://play.google.com/store/apps/details?id=theveshtheva.debatebreaker
EDIT: I'm trying something but it doesn't seem to work. Could someone tell me what I'm doing wrong?
The webpage I'm trying to pull data from is here:
http://ktjdaily.blogspot.com/2015/02/menu-of-day.html
Here's my activity java file:
package theveshtheva.practice;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import android.widget.TextView;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
public class onlinetext extends ActionBarActivity {
private String HTML;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_onlinetext);
/*FROM HERE*/
TextView outtext = (TextView) findViewById(R.id.textView);
try {
getHTML();
} catch (Exception e) {
e.printStackTrace();
}
outtext.setText("" + HTML);
/*TO HERE*/
}
private void getHTML() throws IOException
{
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet("http://ktjdaily.blogspot.com/2015/02/menu-of-day.html"); //URL!
HttpResponse response = httpClient.execute(httpGet, localContext);
String result = "";
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line;
while ((line = reader.readLine()) != null) {
result += line + "\n";
HTML = result;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_onlinetext, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
And here's the Manifest file, where I've set permissions:
<?xml version="1.0" encoding="utf-8" ?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="theveshtheva.practice">
<uses-permission android:name="android.permission.INTERNET" />
<application android:allowBackup="true" android:icon="#drawable/ic_launcher" android:label="#string/app_name" android:theme="#style/AppTheme">
<activity android:name=".onlinetext" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
There are HTTP apis already in Android that do this. There's like an Earthquake monitor sample application that pulls XML via HTTP in a background service.
Start there.
I feel like there is a lot of questions on how to sync android apps with online services or backend systems in general. So basically, I will try to expose here some ways you may have of doing so and I will try to keep it as simple as possible:
1)The world outside your mobile application
Ok, so you want to make an app that sends and retrieves information from through the internet...fine! But first of all, before even thinking about your app, have you thought about your server? the online service that holds the info your app should manipulate? So, yes! Your server/service should be ready and working when you start to think about writing an application that will do any online sync. By the way, a reasonable advice would be to start facing the term "application" as your whole service environment , including mobile apps and everything, not just one single mobile application per say.
If you have your own online service good to go or you just need to use 3rd party online services that are also ready, then that's the end of step 1.
2)Communicating with the outside world
Here you already have your functional online service. Now you need to set ways of communicating with it. Think as the "communication part" as a different project. Don't think it as just a bridge between your mobile app and your backend system. Think it as a bridge for any application from any environment to your system. A unique way that apps can reach your system and your system can reach them, exchanging valuable information for what they concern. We have some options here, but I will stick with the RESTApi. I won't describe here what is a RESTApi and how you actually write code around it(I guess that must be one of your biggest concerns), because someone already did in this epic SO question.
What you really need to understand here is the whole concept and then later you can checkout some frameworks(there are a lot) to actually implement it(you'll see that is the easiest part). To end the step 2, here is a REALLY simple diagram to show it (not the best, I know):
3) Finally, your android app
As using RESTApi , we're going to handle http requests. In order to do so, we have many ways of doing it in our android application. I will provide some code using the built-in HttpClient for better understanding : RestClient.java . This class is a real basic rest client that will do POST and GET http requests by just:
RestClient client = new RestClient();
client.execute("http://youronlineservice.com:3430/api/somegetrequest",RequestMethod.GET);
client.execute("http://youronlineservice.com:3430/api/somepostrequest",RequestMethod.POST);
Now, when dealing with the android environment, be careful with NetworkOnMainThreadException:
The exception that is thrown when an application attempts to perform a networking operation on its main thread.
Therefore, I strong recommend the use of AsyncTask when dealing with simple http requests, because:
AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
AsyncTask is designed to be a helper class around Thread and Handler and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent package such as Executor, ThreadPoolExecutor and FutureTask.
An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params, Progress and Result, and 4 steps, called onPreExecute, doInBackground, onProgressUpdate and onPostExecute.
For ending, as you may be wondering, when you do a http request for your api you have to handle the response that will come. As you will figure out, there will be various types you can treat responses depending on the format you designed your api to work.
Mainly, you'll probably work with XML or JSON. But don't worry! There are plenty of stuff on how working with these formats in your android applications, including some awesome frameworks that you better discover yourself to see what fits you best.
After you're done with this, you may want to check some other stuff to increase the sync experience in your app, such as:
http://developer.android.com/training/sync-adapters/creating-sync-adapter.html
http://developer.android.com/reference/android/app/Service.html
And keep in mind that the best references you can get are here: http://developer.android.com/training/index.html
Hope it can help you and others!
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Android HttpClient : NetworkOnMainThreadException
I have a php script on a server that recieves get requests, and mails out the content.
So lets say we have http://url.com/testmail.php?message=somemessage
the contents of "message" will be sent in an email.
I want my app to be able to call this script, and insert it's own mesage in the request. It will mostly be used for user feedback. I know it would be better to use POST, and if there is some android function that can natively handle mail, please enlighten me as I am new.
This is the code I have at the moment inside my main activities "onCreate", and it is generating exceptions:
HttpClient httpClient = new DefaultHttpClient();
String url = "http://someurl/testmail.php?message=eventualjavavariable";
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse response = httpClient.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
ByteArrayOutputStream out = new ByteArrayOutputStream();
entity.writeTo(out);
out.close();
String responseStr = out.toString();
// do something with response
} else {
// handle bad response
}
} catch (ClientProtocolException e) {
// handle exception
} catch (IOException e) {
// handle exception
}
I also have added this line in my Android Manifest file:
<uses-permission android:name="android.permission.INTERNET"/>
What am I doing wrong?
This is my LogCat:
10-09 15:12:33.185: E/AndroidRuntime(5561): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.fragments/com.example.android.fragments.MainActivity}: android.os.NetworkOnMainThreadException
10-09 15:12:33.185: E/AndroidRuntime(5561): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
10-09 15:12:33.185: E/AndroidRuntime(5561): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
10-09 15:12:33.185: E/AndroidRuntime(5561): at android.app.ActivityThread.access$600(ActivityThread.java:130)
10-09 15:12:33.185: E/AndroidRuntime(5561): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
The application is crashing due to network activity on the main UI thread, which itself is not a very good practice, as the application can stop responding and might get killed by the OS. You should always try to do your background processing in some separate thread, and not on the main UI thread.
You need to make the HttpConnection on a background thread, maybe by using an AsyncTask.
As the name of the exception indicates, you are not allowed to perform a networking operation on the main thread. See the reference documentation.
A NetworkOnMainThreadException 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.
Some examples of other operations that ICS and HoneyComb won't allow you to perform on the UI thread are:
Opening a Socket connection (i.e. new Socket()).
HTTP requests (i.e. HTTPClient and HTTPUrlConnection).
Attempting to connect to a remote MySQL database.
Downloading a file (i.e. Downloader.downloadFile()).
If you are attempting to perform any of these operations on the UI thread, you must wrap them in a worker thread. The easiest way to do this is to use of an AsyncTask, which allows you to perform asynchronous work on your user interface. An AsyncTask will perform the blocking operations in a worker thread and will publish the results on the UI thread, without requiring you to handle threads and/or handlers yourself.
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.
I'm hoping someone can find this problem. I had an app that was fully working in server communications. Unfortunately, I somehow lost my Eclipse workspace when moving to the Windows 8 CP. I still had the .apk, and using Dex2jar and jd-gui, I was able to salvage a lot of code. I've got it all back into working condition, but this. I'm attempting to send a URL to a server, and get back a string response. Here's the code:
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
public class login extends Activity{
<code>
public void pushLogin(View paramView){
try{
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(loginFinal);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
errorTextView.setText(loginFinal);
//code gets here
String response = client.execute(request, responseHandler);
//does not get here
errorTextView.setText(response);
}
My TextView always contains the string loginFinal, I cannot get it to display the response. To check this, I moved the errorTextView.setText(loginFinal); to the line after attempting to get the String response. It didn't run at that point either. I'm tearing my hair out, and I'm sure it's something simple. I've got the internet permission, I even found my original code for this portion of the app on this site as I posted it asking a separate question. This code is, as far as I can tell, identical. The only thing I can think of that changed is I moved my build target from Froyo to Honeycomb, as I decided I want to focus on tablets.
The best part is that LogCat does absolutely nothing when I press the button, triggering pushLogin. It doesn't seem to be triggering the client.execute(request, responseHandler) at all.
You are probably call pushLogin() on UI thread, Note that the thread policy has been changed since API Level 11 (HONEYCOMB), which in short, does not allow network operation (include HttpClient and HttpUrlConnection) get executed on UI thread, otherwise you get NetworkOnMainThreadException. The correct strategy is to call pushLogin() on background thread (AsycnTask as a good example).
Hope this help.