Chris James Hancocks
Chris James Hancocks

Reputation: 323

Using asynctask for network connection

I am trying to incorporate asynctask into my code as I get a force close at the minute due to NetworkOnMainThreadException.

I have gone through a few tutorials but I still cannot get my head around it. Every time I try it out, I just get errors all over the place.

Tutorials I looked at:

  1. [http://developer.android.com/reference/android/os/AsyncTask.html][1]
  2. [https://androidresearch.wordpress.com/2012/03/17/understanding-asynctask-once-and-forever/][2]

Basically what the code is doing is:

  1. Taking an IP Address from an intent.
  2. Connecting to the IP with port 32
  3. Then send a command, wait for response and the send another command.
  4. After the 2 commands our sent I should get a response of "SNX_COM>"
  5. Once the connection is established, I want the connection to stay open to send specific commands on button click.

^^That's basically what my code should achieve ^^

package com.smarte.smartipcontrol;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;

public class IPControl extends Activity {

private Socket socket;
private String serverIpAddress = "com.smarte.smartipcontrol.ACTU_IP";
private static final int REDIRECTED_SERVERPORT = 32;
public PrintWriter out;
public BufferedReader in;
public String data;
public Object pd;



public void getModel(View view) {
    try {
        out.println("[m\r\n");
        //System.out.print("root\r\n");
        while(!in.ready());
        String textStatus = readBuffer();

    } catch(IOException e) {}
}


@Override
public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);

   setContentView(R.layout.act_ipcontrol);


   try{   

    new AsyncAction().execute();

   }catch (Exception e) {
       e.printStackTrace();
   }

   }



private class AsyncAction extends AsyncTask<String, Void, String> {
   protected String doInBackground(String... args) { 
   try {
 InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
 socket = new Socket(serverAddr, REDIRECTED_SERVERPORT);
} catch (UnknownHostException e1) {
 e1.printStackTrace();
} catch (IOException e1) {
 e1.printStackTrace();
}
try {
 out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true); in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
 while (! in .ready());
 readBuffer();
 out.println("root\r\n");
 //System.out.print("root\r\n");
 while (! in .ready());
 readBuffer();
 out.println("root\r\n");
 //System.out.print("root\r\n");
 while (! in .ready());
 String msg = "";

while ( in .ready()) {
 msg = msg + (char) in .read();
}
} catch (IOException e) {}

       return null;//returns what you want to pass to the onPostExecute()
   }

   protected void onPostExecute(String result) {

   //results the data returned from doInbackground

       IPControl.this.data = result;



       }
   }


private String readBuffer() throws IOException {
    String msg = "";

    while(in.ready()) {
        msg = msg + (char)in.read();
    }
    //System.out.print(msg);
    if(msg.indexOf("SNX_COM> ") != -1) return msg.substring(0, msg.indexOf("SNX_COM> "));
    else return msg;
}

}

LogCat

12-03 15:39:56.346: E/AndroidRuntime(2697): FATAL EXCEPTION: AsyncTask #5
12-03 15:39:56.346: E/AndroidRuntime(2697): java.lang.RuntimeException: An error occured while executing doInBackground()
12-03 15:39:56.346: E/AndroidRuntime(2697):     at android.os.AsyncTask$3.done(AsyncTask.java:299)
12-03 15:39:56.346: E/AndroidRuntime(2697):     at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
12-03 15:39:56.346: E/AndroidRuntime(2697):     at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
12-03 15:39:56.346: E/AndroidRuntime(2697):     at java.util.concurrent.FutureTask.run(FutureTask.java:239)
12-03 15:39:56.346: E/AndroidRuntime(2697):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
12-03 15:39:56.346: E/AndroidRuntime(2697):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
12-03 15:39:56.346: E/AndroidRuntime(2697):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
12-03 15:39:56.346: E/AndroidRuntime(2697):     at java.lang.Thread.run(Thread.java:856)
12-03 15:39:56.346: E/AndroidRuntime(2697): Caused by: java.lang.NullPointerException
12-03 15:39:56.346: E/AndroidRuntime(2697):     at com.smarte.smartipcontrol.IPControl$AsyncAction.doInBackground(IPControl.java:71)
12-03 15:39:56.346: E/AndroidRuntime(2697):     at com.smarte.smartipcontrol.IPControl$AsyncAction.doInBackground(IPControl.java:1)
12-03 15:39:56.346: E/AndroidRuntime(2697):     at android.os.AsyncTask$2.call(AsyncTask.java:287)
12-03 15:39:56.346: E/AndroidRuntime(2697):     at java.util.concurrent.FutureTask.run(FutureTask.java:234)
12-03 15:39:56.346: E/AndroidRuntime(2697):     ... 4 more

Upvotes: 3

Views: 1333

Answers (2)

Stupidus
Stupidus

Reputation: 471

Once the connection is established, I want the connection to stay open to send specific commands on button click.

You might have to make a new thread when you want to send commands to the server:

button.setOnClickListener(new OnClickListener()
{
    public void onClick(View arg0)
    {
      new Thread()
      {
        @Override
        public void run()
        {
          methods.sendCommandToServer();
        } 
      }.start(); 
     } 
  });

Upvotes: 1

v0d1ch
v0d1ch

Reputation: 2748

You have to move your createConnection(); to doInBackground() of your asynctask which you have to add as inner class or separate class of your project For example :

 private class DownloadFilesTask extends AsyncTask<Void, Void, Void> {
 protected Void doInBackground(Param[]...) {
     createConnection();
 }

 protected void onProgressUpdate() {
     setProgressPercent(progress[0]);
 }

 protected void onPostExecute() {


 }

}

This is from first link you provided I just changed it a little bit. Make sure you return something from method createConnection() so that you know that asynctask has finished successfully or not and change DownloadFilesTask accordingly so that doInBackground() and onPostExecute() returns the same type

Upvotes: 1

Related Questions