Running Server not in UiThread - android

I want to run my ServerSocket and I know how to do it using Thread, but I want to start it not in Ui, so I was thinking about launch this server using AsyncTask.
I have code:
ServerSocket serversocket = new ServerSocket();
serversocket.execute();
public class ServerSocket extends AsyncTask<Void, Void, String>{
public void DataFetcher(android.support.v4.app.FragmentManager fragmentManager){
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(Void... params) {
String data = null;
Toast.makeText(getApplicationContext(), "server is on", Toast.LENGTH_SHORT).show();
return data;
}
#Override
protected void onPostExecute(String result) {
// make gui thread do some work
}
}
but it's not working, can anyone tell me what should I do?
I have ServerClient running using AsyncTask and i want also run my server liek that ,
here is my code for Client:
public class MyClientTask extends AsyncTask<Void, Void, Void> {
String dstAddress="..."
int dstPort=8080;
String response = "";
MyClientTask(String addr, int port){
dstAddress = addr;
dstPort = port;
}
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
socket = new Socket(dstAddress, dstPort);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "IOException: " + e.toString();
}finally{
if(socket != null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
}
}
}

This is wrong
Toast.makeText(getApplicationContext(), "server is on", Toast.LENGTH_SHORT).show();
Toast runs on the main thread and since you can't update UI elements in a background Thread you can't call it from doInBackgroud()
You can do this in onPostExecute() or in onProgressUpdate() by calling publishProgress() in doInBackground()
If it still isn't working then define "but it's not working". That is not a very helpful summary of what is/isn't happening.
I know how to do it using Thread, but I want to start it not in Ui
If you are running it in a separate Thread then it is not running on the UI Thread

Related

Trying to use AsyncTask to update server periodically

I have a method that need to update its status periodically to the server.
I am using AsyncTask to run the HTTP call in background.
PROBLEM: In onPostExecute method upon checking AsyncTask.getStatus, It show the previous task still running which is causing the error.
ERROR: java.lang.IllegalStateException: Cannot execute task: the task is already running.
DIFFERENT STRATEGIES USED TO SOLVE THE PROBLEM BUT NONE IS WORKING
1. Before Relaunching AsyncTask, checked the status, it is showing the thread is RUNNING.
2. Called the AsyncTask.cancel(true), immediately before calling the AsyncTask.execute if it is still running. It turns out AsyncTask still RUNNING and taking more than 3 mins to get cancel.
NOTE: I have checked many similar questions here, but haven't found helpful.
I would really appredicae if any one of you guys give me an example to solve this issue, Thanks a Million in advance......
public class MainActivity extends Activity implements AsyncResponse{
ConnectServer asyncTask =new ConnectServer();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
asyncTask.delegate = this;
setContentView(R.layout.activity_main);
//Start updating server using below method
loop();
}
public void processFinish(String output){
//this you will received result fired from async class of onPostExecute(result) method.
//Log.v(TAG, output);
if(output != null){
//not using this at this point
}
}
//Method that will call Async method to reach server
public void loop(){
TextView b = (TextView) findViewById(R.id.mField);
String str;
try {
str = asyncTask.execute(true).get();
b.setText(str);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// START SERVER CONNECTION
class ConnectServer extends AsyncTask<Boolean, String, String> {
public AsyncResponse delegate=null;
public int i = 0;
private Activity activity;
public void MyAsyncTask(Activity activity) {
this.activity = activity;
}
#Override
protected String doInBackground(Boolean... params) {
String result = null;
StringBuilder sb = new StringBuilder();
try {
// http post
HttpClient httpclient = new DefaultHttpClient();
HttpGet httppost = new HttpGet("http://192.168.0.21:8080");
HttpResponse response = httpclient.execute(httppost);
if (response.getStatusLine().getStatusCode() != 200) {
Log.d("GPSApp", "Server encountered an error");
}
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF8"));
sb = new StringBuilder();
sb.append(reader.readLine() + "\n");
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
result = sb.toString();
} catch (Exception e) {
Log.e("log_tag", "Error converting result " + e.toString());
}
return result;
}
#Override
protected void onPostExecute(String result) {
TextView mField = (TextView) findViewById(R.id.mField);
mField.setText(result+i);
try {
Thread.sleep(10000);
//asyncTask =new ConnectServer();
i++;
String str = asyncTask.execute(true).get();
mField.setText(str+i);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected void onPreExecute() {}
}
}
Call getStatus() to get the status of AsyncTask. If the status is AsyncTask.Status.RUNNING, cancel it.

AsyncTask and Telnet doesn't show ProgressDialog

I am using an asynctask while I am doing some telnet operations. However, the progressdialog is not shown, and I am almost 100% sure that Telnet is the cause.
Please take a look to my code and help me to find where is the problem.
Thanks
public class TelnetManager extends AsyncTask<String, Void, String>{
private TelnetClient telnet;
private int port;
private String IP;
private ProgressDialog dialog;
private Context context;
public TelnetManager(Context c,String IP, int port, String user, String pass)
{
context=c;
this.IP=IP;
this.port=port;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog=new ProgressDialog(context);
dialog.setMessage(context.getResources().getString(R.string.msg_wait));
dialog.show();
}
public String readString() throws IOException
{
InputStream in = new BufferedInputStream(telnet.getInputStream());
int read=0;
String s=null;
do
{
byte[] buffer = new byte[1024];
read = in.read(buffer);
if(read > 0)
{
if(s==null)s=new String(buffer, 0, read);
else s+=new String(buffer, 0, read);
Log.e("S",s);
}
}
while (read > 0);
in.close();
return s;
}
public void writeString(String command) throws IOException
{
OutputStream out = telnet.getOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(out,"UTF-8");
writer.write(command+'\n');
writer.flush();
}
#Override
protected String doInBackground(String... params) {
telnet = new TelnetClient();
String s="";
try {
telnet.setConnectTimeout(10000);
telnet.connect(IP,port);
telnet.setKeepAlive(true);
writeString("password");
writeString(params[0]);
writeString("exit");
String aux=readString();
telnet.getInputStream().close();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
telnet.disconnect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return s;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(dialog!=null && dialog.isShowing())
{
dialog.dismiss();
}
}
}
And here is where I call the AsyncTask:
String list=null;
try {
list=new TelnetManager(this,"192.168.11.30", 10010, null, null).execute("son").get();
construirLayout(list,R.id.containerON);
list=new TelnetManager(this,"192.168.11.30", 10010, null, null).execute("soff").get();
construirLayout(list,R.id.containerOFF);
}
catch (InterruptedException e) {
Toast.makeText(this,"InterruptedException",3000).show();
e.printStackTrace();
}
catch (ExecutionException e) {
Toast.makeText(this,"ExecutionException",3000).show();
e.printStackTrace();
}
If you call get() on an AsyncTask, you're telling the UI thread to block and wait for the AsyncTask results. Since the UI thread is blocked, it cannot show the ProgressDialog.
You should instead provide a callback to the AsyncTask, to be fired in onPostExecute().

Communicating with a server using Asynctask when the timertask finishes

I'm using a TimerTask to get the result of a Wi-Fi scan on a specific interval. I want to send the scanning results to a server.So I used AsyncTask to send the results. When I call the AsyncTask from inside the TimerTask my application crashes. Can anyone tell me why this is happening? Also in my code what is the best way to send the result to a server?
Here is my code:
public class ServerComm extends AsyncTask<String, Void, String>{
int port=9999;
String IP="192.168.2.100";
BufferedReader input;
#Override
protected String doInBackground(String... scanRes) {
// TODO Auto-generated method stub
Socket socket;
String loc="";
FileWriter writer;
File sock=new File(Environment.getExternalStorageDirectory()+"/network.txt");
try {
writer = new FileWriter(sock, true);
writer.append("in async task.\n");
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
InetAddress serverAddr = InetAddress.getByName(IP);
socket = new Socket(serverAddr, port);// socket is created
input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Log.d("ser","socket");
// now send
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
out.println(scanRes);
// get the reply
loc = input.readLine();
//close
socket.close();
return loc;
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return loc;
}
#Override
protected void onPostExecute(String result) {
// draw the new location on the map
}
This is the code of the TimerTask:
public void Locate()
{
if(isScanning)// if a previous scan is running cancel it
{
timer.cancel();
}
else
{
timer.schedule(new TimerTask() { // start new scanner
#Override
public void run() {
// TODO Auto-generated method stub
if(counter==numOfScans)
{
try {
writer = new FileWriter(file, true);
writer.append(RSS+" \n");
writer.append("Finished Collecting RSSIs.\n");
writer.close();
new ServerComm().execute(RSS);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
timer.cancel();
}
else // not finished
{
isScanning=true;
if(result!=null)
{
if(result.size()!=0)
{
for(int i=0;i< result.size();i++)
{
RSS=RSS+result.get(i).BSSID+" "+result.get(i).level+" ";
}//end for
counter++;
} // end of if
}//end of else
}
}
}, 0,Interval);
}
//get location
}
I solved the problem, so I'm posting the answer in case someone else faced the same problem.
The problem was the AsyncTask should not be called from TimerTask. A handler should be used to run the AsyncTask Like this:
Handler h = new Handler(Looper.getMainLooper());
h.post(new Runnable() {
public void run() {
new ServerComm().execute(RSS);
}
});
This is solution is by arthvading on this question.

App not responding while transfer data

I am sending image using Socket Server and Client. It gived me dialog "App not responding" i think beacuse converting this bitmap was making in UiThread. So i tried to change it but i am still getting this message "App is not responding". It's happening when i am sending big imaes +500kb.
Here is my code for Server:
public class SocketServerThread extends Thread {
static final int SocketServerPORT = 8080;
int count = 0;
#Override
public void run() {
try {
serverSocket = new ServerSocket(SocketServerPORT);
while (true) {
Socket socket = serverSocket.accept();
count++;
// Here where i am doing my code i think is not doing in UiThread..
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run()
{
// Firstly i was doing my code here...
}
});
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
My code for client:
public class MyClientTask extends AsyncTask<Void, Void, Void> {
MyClientTask(String addr, int port){
dstAddress = addr;
dstPort = port;
}
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try
{
//I am sending my image here...
}
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "IOException: " + e.toString();
}finally{
if(socket != null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
}
}
So please help my . Why still i am getting not responding dialog?
The ANR error code happens when you block the UI thread more than 5 seconds. If you need to do background work don't use the main thread. Receive the data in a separate thread and post only the result to the UI thread.

How to avoid Jsoup and Asynctask crash if server down

I need some help.
I developed an app that parse a web site.
Everything works great now (also thanks to you). But i'm facing a problem when the site that I want to parse is down.
The app just crashes ... I tryed to improve timeout connection, and this works when site is just slow. But how I can manage the server down error?
I would like to print an error in a textview o something like that.
this is part of my code
String result = "";
Document doc = null;
try {
Connection conn = Jsoup.connect(BLOG_URL).timeout(14000);
doc = conn.get();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
handle the crash when server is down like shown below.
private class doSomethingDelayed extends AsyncTask<Void, Integer, Void> {
private int num_runs = 0;
#Override
protected Void doInBackground(Void... gurk) {
try {
//stuffs...
publishProgress(num_runs);
} catch (ClientProtocolException e) {
} catch (IOException e) {
serviceAvailable = true;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (serviceAvailable == true) {
serviceAvailable = false;
Toast.makeText(getApplicationContext(), "Service not available", Toast.LENGTH_SHORT).show();
System.out.println("in onPostExecute method --");
}
}
#Override
protected void onProgressUpdate(Integer... num_runs) {
try {
} catch (JSONException e) {
e.printStackTrace();
}
}
}

Categories

Resources