how to use another thread to stop NetworkOnMainThreadException? - java

I am trying to access the android network by starting a TCP server. But when I create a new thread, either by
Thread t = new Thread(runnable);
t.start();
or FutureTask I still get the networkonmainthreadexception...

Use AsyncTask to perform network related ops
For Example :
private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String response = "";
for (String url : urls) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse execute = client.execute(httpGet);
InputStream content = execute.getEntity().getContent();
BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null) {
response += s;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return response;
}
#Override
protected void onPostExecute(String result) {
textView.setText(result);
}
}
Or you can do this, Although it is not recommended
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy =
new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
adding this code will not give you network on main thread exception anymore.

You have to do the actual network IO on the run() function of the runnable in the thread. You don't just create a thread and then do the IO.

Related

Is there an Alternative for AsyncTask using HttpUrlConnection

Using AsyncTask freezes my whole app. i have an icon that rotates while the Http action is happening in the background. but the app just freezes till it finishes that action. Is there an alternative?
The below class sends the JSON to the server, the server has multiple endpoints and stuff like that. now when calling class calls the execute() method, the app freezes until the task is complete.
public class Connector extends AsyncTask<String, Void, Void> {
private String ip = "http://192.168.1.127";
private String port = "5000";
private URL Url;
private JSONObject jsonObject;
private String method = "";
private StringBuilder output = new StringBuilder();
Connector(String url, JSONObject jsonObject, String method)
{
try {
this.method = method;
this.Url = new URL(ip+":"+port+url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
this.jsonObject = jsonObject;
//Connect to URL
}
#Override
protected Void doInBackground(String... strings) {
try {
HttpURLConnection httpURLConnection = (HttpURLConnection) Url.openConnection();
Log.i("Data", "Data sent => " + jsonObject.toString());
try {
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
httpURLConnection.setRequestMethod(method);
httpURLConnection.setRequestProperty("content-type", "application/json");
httpURLConnection.connect();
DataOutputStream outputStream = new DataOutputStream(httpURLConnection.getOutputStream());
if(jsonObject != null)
{
outputStream.writeBytes(jsonObject.toString());
outputStream.flush();
outputStream.close();
}
InputStreamReader inputStreamReader = new InputStreamReader((InputStream) httpURLConnection.getContent(), Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while(line != null)
{
output.append(line);
line = reader.readLine();
}
}finally {
httpURLConnection.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
String getMessge() {
Log.i("Data", "Data received <= " + output.toString());
return output.toString();
}
}
Please use Retrofit library.
You can find samples to use Retrofit easily.
https://www.journaldev.com/13639/retrofit-android-example-tutorial
This is one of them.
Hope it to help you. Thanks.

displaying notifications from onprogressUpdate method from asynctask class

i am trying to send a notifications from the on progressupdate method from the asynctack class. Since i am a newbie to android, i don't know where seem to be the error. The AllSensorData is a separate java clas. It would be great if you could help. thanks
Here's my code for the asyntack class
public class AllSensorData extends AsyncTask<String, byte[], String>{
TextView temp,humi,motion,smoke,flame,water,reed,data;
int notificationID = 1;
NotificationManager notificationManager =null;
Context context;
public AllSensorData(TextView temp,TextView humi,TextView motion,TextView smoke,TextView flame,TextView water,TextView reed) {
this.temp=temp;
this.humi=humi;
this.motion=motion;
this.smoke=smoke;
this.flame=flame;
this.water=water;
this.reed=reed;
}
InputStream nis;
OutputStream nos;
BufferedReader in;
DefaultHttpClient httpclient =new DefaultHttpClient();
URL url;
URLConnection urlconn=null;
InputStreamReader isn;
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
try {
while(true){//while connected
HttpGet httpget =new HttpGet("http://192.168.1.177/");
response = httpclient.execute(httpget);
in=new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String msgFromServer = in.readLine();//read the lines coming from the socket
byte[] theByteArray = msgFromServer.getBytes();//store the bytes in an array
publishProgress(theByteArray);//update the publishProgress
if(isCancelled()){
break;
}
}
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
return null;
}
protected void onProgressUpdate(byte[]... values) {
super.onProgressUpdate(values);
String command=new String(values[0]);//get the String from the recieved bytes
String[] parts= command.split(",");
String part1=parts[0];
String part2=parts[1];
temp.setText(part1);
humi.setText(part2);
if(Integer.parseInt(part2)>70)
{
NotificationCompat.Builder builder=new NotificationCompat.Builder(this.context);
builder.setContentTitle("AM Home Automation");
builder.setContentText("humidity > 70");
builder.setSmallIcon(R.drawable.ic_launcher);
builder.setTicker("alert");
builder.setDefaults(Notification.DEFAULT_ALL);
//builder.setSound(Uri.parse("android.resource://"+getPackageName()+"/"+R));
notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notificationID, builder.build());
notificationID++;
}
}
}
as i was going through the code, I dont think that context is initialized properly although it has been declared in the class. Could you cross check that it has beeen initialized before it is used anywhere in the class ( specially in notification builder)
try making the following change in the class
public AllSensorData(TextView temp,TextView humi,TextView motion,TextView smoke,TextView flame,TextView water,TextView reed, Context context) {
this.temp=temp;
this.humi=humi;
this.motion=motion;
this.smoke=smoke;
this.flame=flame;
this.water=water;
this.reed=reed;
this.context=context
}
Also, remember to pass application context when you initialize this class as follows from your main activity:
AllSensorData mSensorData = new AllSensorData(temp, humi, motion, smoke, flame, water,reed,getApplicationContext());
That might just solve your problem!

AsyncTask to display Response form WCF

I wrote a Restful WCF service and it is deployed on IIS. I have been attempting to consume the WCF Service using a AsyncTask Thread. I built the thread in to the main UI class so that I can update the GUI.
public class ServiceRunning extends AsyncTask<String, Void, String>{
private Exception exception;
String line = "";
public void setLine(String line)
{
this.line = line;
}
public String getLine()
{
return line;
}
#Override
protected String doInBackground(String... url) {
try
{
DefaultHttpClient httpClient = new DefaultHttpClient();
URI uri = new URI(url[0]);
HttpGet httpget = new HttpGet(uri);
httpget.setHeader("Accept", "application/json");
httpget.setHeader("Content-type", "application/json; charset=utf-8");
HttpResponse response = httpClient.execute(httpget);
HttpEntity responseEntity = response.getEntity();
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
// while ((line = rd.readLine()) != null) {
// Log.d("****Status Line***", "Webservice: " + line);
// }
while((line = rd.readLine()) != null)
{
setLine(line);
Log.d("****Status Line***", "Webservices: " + getLine());
}
}
catch (Exception e)
{
e.printStackTrace();
}
return "String :" + line;
}
protected void onPostExecute(String result) {
TextView txt = (TextView)findViewById(R.id.textView1);
txt.setText(getLine());
}
}
In the code, I write the response to a String and I attempt to display it after execution. For some resound, when I run the program I don't get the response, I get a blank TextView but the message displays in the Eclipse LogCat. I cant find the problem, what causes this?
AsyncTask is tied to the activity kicking it off. If you rotate the device or the app goes into the background, is added or removed from a dock, the original activity is destroyed. The AsyncTask continues though and responds to the original activity that is no longer visible.
You are better off using an IntentService or Service to call web services, it is a much more reliable pattern.

Post JSON in android

I want to post String data over HttpClient in android
but i'm tired after receive response status code 503 - service unavailable and
return response as Html code for our url.
I write in the following Code in JAVA Application and i return the data but when I write the same code in Android Application i receive an exception file I/O not found, I'm Puzzled for this case:
public void goButton(View v)
{
try{
URL url = new URL("https://xxxxxxxxx");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
Test ts= new ApiRequest("null","getUserbyID",new String[] { "66868706" });
String payLoad = ts.toString(); //toSting is override method that create //JSON Object
System.out.println("--->>> " + payLoad);
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
System.out.println("=================>>> "+ payLoad);
wr.write(payLoad);
wr.flush();
BufferedReader rd = new BufferedReader(new nputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
System.out.println("-->> " + line);
response += line;
}
wr.close();
rd.close();
System.out.println("=================>>> "+ response);
} catch (Exception e) {
e.printStackTrace();
System.out.println("=================>>> " + e.toString());
throw new RuntimeException(e);
}
I try to put this code in AsynTask, Thread but i receive the same response status code.
I write in the following Android code as an example data
public void goButton(View v)
{
try{
new Thread(new Runnable() {
public void run() {
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(),
10000); // Timeout Limit
HttpResponse response;
String url = "https://xxxxxxxxxxxxx";
JSONObject json = new JSONObject();
try {
HttpPost post = new HttpPost(url);
post.setHeader("Content-type", "application/json");
json.put("service","null");
json.put("method", getUserByID.toString());
json.put("parameters", "1111");
System.out.println(">>>>>>>>>>>" + json.toString());
StringEntity se = new StringEntity(json.toString());
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE,
"application/json"));
post.setEntity(se);
String response = client.execute(post);
if (response != null) {
String temp = EntityUtils.toString(response.getEntity());
System.out.println(">>>>>>>>>>>" + temp);
}
} catch (Exception e) {
e.printStackTrace();
System.out.println(">>>>>>>>>>>" + e.getMessage());
}
}
}).start();
}
Please Help me to find solution for this problem :(
Thank you in advance
Here is an code snippet , hoping it will help you.
1)An function which carries the http get service
private String SendDataFromAndroidDevice() {
String result = "";
try {
HttpClient httpclient = new DefaultHttpClient();
HttpGet getMethod = new HttpGet("your url + data appended");
BufferedReader in = null;
BasicHttpResponse httpResponse = (BasicHttpResponse) httpclient
.execute(getMethod);
in = new BufferedReader(new InputStreamReader(httpResponse
.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
while ((line = in.readLine()) != null) {
sb.append(line);
}
in.close();
result = sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
2) An Class which extends AsyncTask
private class HTTPdemo extends
AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {}
#Override
protected String doInBackground(String... params) {
String result = SendDataFromAndroidDevice();
return result;
}
#Override
protected void onProgressUpdate(Void... values) {}
#Override
protected void onPostExecute(String result) {
if (result != null && !result.equals("")) {
try {
JSONObject resObject = new JSONObject(result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
3) Inside your onCreate method
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView("your layout");
if ("check here where network/internet is avaliable") {
new HTTPdemo().execute("");
}
}
This code snippet ,
Android device will send the data via URL towards Server
now server needs to fetch that data from the URL
Hey Mohammed Saleem
The code snippet provided by me works in the following way,
1)Android device send the URL+data to server
2)Server [say ASP.NET platform used] receive the data and gives an acknowledgement
Now the Code which should be written at client side (Android) is provided to you, the later part of receiving that data at server is
Server needs to receive the data
An webservice should be used to do that
Implement an webservice at server side
The webservice will be invoked whenever android will push the URL+data
Once you have the data ,manipulated it as you want

Set a Timeout to a Thread Class

Hy!!
I have a thread class and want to set a timeout inside after 10 sec.
How is this been made?
Class:
public class HttpConnection extends Thread{
List<NameValuePair> list;
String url;
Handler handler;
public HttpConnection(List<NameValuePair> params, String url, Handler handler) {
this.list = params;
this.url = url;
this.handler = handler;
}
#Override
public void run() {
try
{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
String result;
BufferedReader in = null;
httppost.setEntity(new UrlEncodedFormEntity(this.list));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
if(response != null){
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
Message msg = Message.obtain();
if ((result = sb.toString()) != null)
{
msg.obj = result;
}
else
{
msg.obj = null;
throw new Exception("ERROR");
}
handler.sendMessage(msg);
}
}
catch (Exception e)
{
Log.e("XXX", e.getMessage());
}
super.run();
}
}
httpclient.getParams().setParameter("http.socket.timeout", 10000);//10 seconds
the httpconnection will timeout in 10 seconds, probably throwing some exception, in which case you can end your thread
In Java you should be able to use the ThreadPoolExecutor's awaitTermination method to set a timeout. Whichever class is creating and executing this thread should be able to call awaitTermination on the executor for 10 seconds. Is this what you are trying to do (set a timeout ON or WITHIN your thread)?
threadPoolExecutor.awaitTermination(10, TimeUnit.SECONDS);
i may not sure we can use thread handler for these kind of tasks,you better use Asynchronous task for this purpose because it depends up on internet strength availability,it may takes more time to get response from server, so go through developer.android.com for this topic.
super.run();
to
handler.postDelayed(this, 10000);
Hope it's help.

Categories

Resources