PrintWriter giving null pointer exception - java

I am trying to build a multiple client single java server model. I'm doing this using threads, so I have one thread per client using AsyncTask. Thus, I am creating a client socket and the PrintWriter object in the onCreate() method using the CreateClient class and then every time the button2 is pressed, I just need to pass the question/text to the server for that particular thread. The problem is, I am getting a NullPointerException in the SendMessage class.
Here's my Client Actvity:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;
//import statements for client
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import android.speech.RecognizerIntent;
import android.speech.tts.TextToSpeech;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast;
//import statements for client
import android.os.AsyncTask;
public class MainActivity extends Activity implements OnClickListener {
EditText question;
//Client sockets
private Socket client;
private PrintWriter printwriter;
private String toTag;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// create client as soon as the activity starts
CreateClient clientConnection = new CreateClient();
clientConnection.execute();
question = (EditText)findViewById(R.id.editText1);
Button query = (Button)findViewById(R.id.button2);
query.setOnClickListener(this);
ImageButton listen = (ImageButton)findViewById(R.id.button1);
listen.setOnClickListener(this);
listen.performClick();
}
private class CreateClient extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
try {
client = new Socket("Server IP Address", 4444);
printwriter = new PrintWriter(client.getOutputStream(), true);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
private class CloseClient extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
if(printwriter != null) {
try {
printwriter.write("\n");
printwriter.close();
client.close(); // closing the connection
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
private class SendMessage extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
printwriter.write(toTag); // GETTING NULL POINTER EXCEPTION ON THIS LINE
printwriter.write("\n"); //delimiter
printwriter.flush();
return null;
}
}
public void onClick(View v)
{
switch(v.getId())
{
case R.id.button2:
if(validate()) //Validate is a function that validates the text
{
toTag = question.getText().toString();
//Invoke the execute method of AsynTask, which will run the doInBackground method of SendMessage Class
SendMessage sendMessageTask = new SendMessage();
sendMessageTask.execute();
}
else
{
//Toast error msg
}
break;
}
}
#Override
public void onBackPressed() {
super.onBackPressed();
CloseClient closeConnection = new CloseClient();
closeConnection.execute();
}
}

Chances are that the line
printwriter = new PrintWriter(client.getOutputStream(), true);
isn't being executed in time. Try adding a println or initializing the printWriter somewhere else.

printWriter Object has not been initialized and it is still null which is causing Null Pointer Exception
printwriter.write(toTag);// at this line -->
So initialize printWriter=new PrintWriter(); before using it

Well, turns out my client socket wasn't getting created due to outdated DDMS in Eclipse. Something about DDMS not able to create a localhost connection on port 8600. So, as Tyler pointed, my printwriter = new PrintWriter(); statement wasn't getting executed. I updated DDMS and now it works just fine.

Related

How can I use a variable outside the onPostExecute method?

I have a MySQL database on a webserver and I read the data from this database in my application, but after I read the variables I can't use the "volt" variable outside the onPostExecute. I try t use adapter, but i can't use the data in the adapter like a intiger variable, just i can add to listview. So far i Don't find a solution for my problam.
I hope you can help me.
package com.example.wifis;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
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.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URI;
public class MainActivity extends AppCompatActivity {
ListView listView;
ArrayAdapter<String> adapter;
// int tomb []={};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView=(ListView)findViewById(R.id.list_item);
adapter= new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
listView.setAdapter(adapter);
new Conection().execute();
}
class Conection extends AsyncTask<String, String, String>{
#Override
public String doInBackground(String... strings) {
String result="";
String host="http://localhost/store/cars.php";
try {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet();
request.setURI(new URI(host));
HttpResponse response = client.execute(request);
BufferedReader reader= new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer stringBuffer= new StringBuffer("");
String line = "";
while ((line = reader.readLine()) !=null ){
stringBuffer.append(line);
break;
}
reader.close();
result = stringBuffer.toString();
}
catch (Exception e){
return new String("There exeption: "+ e.getMessage());
}
return result;
}
#Override
public void onPostExecute(String result){
// Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show();
JSONObject jsonResult = null;
try {
jsonResult = new JSONObject(result);
int success = jsonResult.getInt("success");
if(success==1){
JSONArray cars = jsonResult.getJSONArray("cars");
JSONObject car = cars.getJSONObject(0);
int id = car.getInt("id");
int volt = car.getInt("szam");
String line = id + "-" + volt;
adapter.add(line);
// tomb[0]=szam;
}else{
Toast.makeText(getApplicationContext(), "NOT OK ", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
As I have tried to explain in my post here
the values you're trying to access aren't synchronous, meaning that your code does not execute top down. The AsyncTask returns a value at some point. we don't know when that will be, but when it returns the value, you'll have access to it within onPostExecute. this means that you can make use of the values as they are received there and only there, as that is the only place where you'll actually receive those values.
to get this value returned to your main activity, you can do something like this :
create an interface
public interface MyCallback {
void myResult(YourResultType output); //here, i believe this will be string for your specific case
}
This interface allows us to move the value we receive to another class when it's received
Next,
Go to your AsyncTask class, and declare interface MyCallback as a variable :
public class MyAsyncTask extends AsyncTask<String, String, String> {
public MyCallback callback = null;
#Override
protected void onPostExecute(String result) {
callback.myResult(result);
}
}
#Override
protected void onPostExecute(String result) {
callback.myResult(result);
}
now for your main activity:
public class MainActivity implements MyCallback {
MyAsyncTask asyncTask = new MyAsyncTask();
#Override
public void onCreate(Bundle savedInstanceState) {
//set your listener to this class
asyncTask.callback = this;
//execute the async task
asyncTask.execute();
}
//this overrides the implemented method from asyncTask
#Override
void myResult(YourResultType output){
//Here you will receive the result returned from the async task
}
}
please also note that async tasks are deprecated
also note, my java is quite rusty, I am fortunate enough to only use kotlin these days, feel free to correct me on any mistakes :)

Error setting java class as object in MainActivity android studio -- cannot resolve symbol ""

I'm a beginner and I have been following several tutorials in order to parse JSON. I am just about to compile and try to run for the first time but when I tried to make an object of my java class and have the process run when the button "click" is triggered, I get an error stating " Cannot resolve symbol "fetchData" "
package com.example.h.arbitrage;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
Button click;
public static TextView data;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
click = findViewById(R.id.button);
data = findViewById(R.id.fetcheddata);
click.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
fetchData process = new fetchData();
((fetchData) process).execute();
}
});
}
}
I'm also including the code for fetchData.java in case there's something in there that's causing this.
I've looked all over for the answer and it might be very obvious but I don't even have the terminology to properly research this...
import android.net.UrlQuerySanitizer;
import android.os.AsyncTask;
import com.example.h.arbitrage.MainActivity;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class fetchData extends AsyncTask<Void,Void,Void> {
String data = "";
#Override
protected Void doInBackground(Void... voids) {
try {
URL url = new URL("https://");
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line ="";
while(line != null){
line = bufferedReader.readLine();
data = data + line;
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
MainActivity.data.setText(this.data);
}
}
Thanks in advance for any help.

TCP from android to PC not working using java

I am trying to send a simple message over TCP from my android phone (using java application) to my computer. I have an socket that is listening on my computer but as soon as I run this app, it crashes. I am really new to Android developing so please bear with me...
Here is my Java code:
package com.scorekeep.clienttcp;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
EditText textOut;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Socket socket = null;
try {
socket = new Socket("10.0.0.10",5000);
DataOutputStream DOS = new DataOutputStream(socket.getOutputStream());
DOS.writeUTF("HELLO_WORLD");
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
As requested an extended example :
import android.app.*;
import android.os.*;
import android.util.*;
import java.io.*;
import java.net.*;
public class MainActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new connection().execute();
}
}
class connection extends AsyncTask<String,String,String> {
public static PrintWriter out;
BufferedReader in;
public static boolean running = true;
#Override
protected String doInBackground(String... message) {
try
{
InetAddress serverAddr = InetAddress.getByName("localhost");
Socket socket = new Socket(serverAddr, 8008);
// send the message to the server
out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())), true);
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
while(running) {
String msgfromserver = in.readLine();
}
}
catch (Exception e)
{}
return null;
}
public static void sendmsg(String msg){
if(out!=null){
out.println(msg);
out.flush();
}
}
}
Usage:
Call connection.sendmsg("some text"); from OnClick method of button
And set connection.running = false; onbackpress. (Or before finishing activity)
You cannot execute background tasks like socket connection in ui thread. You should use AsyncTask.
Example
import android.app.*;
import android.os.*;
import android.util.*;
import java.io.*;
import java.net.*;
public class MainActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new connection().execute();
}
}
class connection extends AsyncTask<String,String,String> {
#Override
protected String doInBackground(String... message) {
try
{
InetAddress serverAddr = InetAddress.getByName("ip here");
Socket socket = new Socket(serverAddr, 5000); //port here
// send the message to the server
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())), true);
out.println("hi");
out.flush(); //optional
socket.close();
}
catch (Exception e)
{}
return null;
}
}
Note Untested. May contain errors.
Two changes in code. public static void sendmsg and public public static PrintWriter out at begining of AsyncTask class

Unable to manage multiple clients (android devices) for a single java server

I need my server to keep track of each of it's client's connection. I've been advised to use Threads. So what I'm trying to achieve is to create a Thread for each client, which should run till the client connection exists. But what is happening is that for each message any client sends, a new client connection gets created in the doInBackground() function. So instead of having one single thread for one single client, I'm getting one thread for any client message sent to the server. Can you suggest a method in with which my server would be able to distinguish different messages sent from different clients?
Java Server Code :
package com.nss.academyassistserver;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class AcademyAssistServer {
public static ServerSocket serverSocket;
public static Socket clientSocket;
static final int PORT = 4444;
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
serverSocket = new ServerSocket(PORT); // Server socket
} catch (IOException e) {
System.out.println("Could not listen on port: "+PORT+" \n");
}
System.out.println("Server started. Listening to the port "+PORT);
while (true) {
try {
clientSocket = serverSocket.accept();
System.out.println("New connection accepted."); // accept the client connection
} catch (IOException ex) {
System.out.println("Problem in message reading");
}
//new thread for a client
new EchoThread(clientSocket).start();
}
}
}
class EchoThread extends Thread {
InputStreamReader inputStreamReader;
BufferedReader bufferedReader;
String fromClient;
Socket clientSocket;
public EchoThread(Socket clientSocket) {
this.clientSocket = clientSocket;
}
public void run() {
try {
inputStreamReader = new InputStreamReader(clientSocket.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader); // get the client message
} catch (IOException e) {
return;
}
while (!Thread.currentThread().isInterrupted()) {
System.out.println("I am thread " + Thread.currentThread().getId());
try {
fromClient = bufferedReader.readLine();
if ((fromClient == null) || fromClient.equalsIgnoreCase("exit")) {
System.out.println("You're welcome, bye!");
return;
} else {
System.out.println(fromClient);
Thread.currentThread().interrupt();
}
} catch (IOException e) {
e.printStackTrace();
return;
}
}
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client Activity Code:
package com.nss.academyassist;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;
//import statements for client
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast;
//import statements for client
import android.os.AsyncTask;
public class MainActivity extends Activity implements OnClickListener {
EditText question;
//Client sockets
private Socket client;
private PrintWriter printwriter;
private String toTag;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
question = (EditText)findViewById(R.id.editText1);
Button query = (Button)findViewById(R.id.button2);
query.setOnClickListener(this);
}
private class SendMessage extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
try {
client = new Socket("Server IP Address", 4444);
printwriter = new PrintWriter(client.getOutputStream(), true);
printwriter.write(toTag); // write the message to output stream
printwriter.flush();
printwriter.close();
client.close(); // closing the connection
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
public void onClick(View v)
{
switch(v.getId())
{
case R.id.button2:
toTag = question.getText().toString();
// Output the result
Toast.makeText(getApplicationContext(), toTag,
Toast.LENGTH_LONG).show();
//Invoke the execute method of AsynTask, which will run the doInBackground method of SendMessage Class
SendMessage sendMessageTask = new SendMessage();
sendMessageTask.execute();
break;
}
}
}
You can use IP to tell the clients. Use
clientSocket.getInetAddress().getHostAddress()
You can also keep the client not closed in the android code. For example, you may open the Socket in onCreate and close it in onDestroy.
The cause for your problem is in your client code. Using new Socket(..) your client will create a new connection each time it sends a tag to the the server. So instead of that you could create a single connection that is reused:
public class MainActivity extends Activity implements OnClickListener {
/* .. your other variables .. */
private Socket client;
private PrintWriter printwriter;
#Override
protected void onCreate(Bundle savedInstanceState) {
/* .. no change here .. */
}
public void onStart()
{
if(this.client != null)
{
try {
client = new Socket("Server IP Address", 4444);
printwriter = new PrintWriter(client.getOutputStream(), true);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void onClose()
{
this.printwriter.close();
this.printwriter = null;
this.client.close();
this.client = null;
}
private class SendMessage extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
try {
printwriter.write(toTag); // write the message to output stream
printwriter.write("\n"); // delimiter
printwriter.flush();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
public void onClick(View v)
{
switch(v.getId())
{
case R.id.button2:
toTag = question.getText().toString();
// Output the result
Toast.makeText(getApplicationContext(), toTag,
Toast.LENGTH_LONG).show();
//Invoke the execute method of AsynTask, which will run the doInBackground method of SendMessage Class
SendMessage sendMessageTask = new SendMessage();
sendMessageTask.execute();
break;
}
}
}
In addition to that you should append some delimiter to your tag/message in order for the server to be able to distinguish the content from different messages.
Since you are using BufferedReader.readLine() which seperates lines
by any one of a line feed ('\n'), a carriage return ('\r'), or a
carriage return followed immediately by a linefeed
I added a line that appends a line feed after the tag in the example above for that purpose.

TCP/IP Connects and Sends But Doesn't Work After Initial Sends

HELP! I'm Going Crazy! I'm using a Visual Basic 6.0 Winsock for the server. I'm able to keep an active connection and I even receive from my Android App to the VB App "VER:Android,LAT:28.111921,LNG:-81.950433,ID:1038263,SND:0,VDO:0"> Which I parse and put the data in their fields.
After my initial connection I try to send a simple message from VB to the Server and I never receive it. What I do notice whenever I close my VB.NET app I recieve this in my LogCat:
11-26 15:38:16.567: I/TcpClient(986): received: null
I'm new to Android any help would be highly appreciated. I need help trying to recieve and send messages back and forth through my Client(Android) and Server(VB)
package com.WheresMySon;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View.OnClickListener;
import android.widget.TextView;
public class TcpClient extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new TcpClientTask().execute();
}
class TcpClientTask extends AsyncTask<Void, Void, Void> {
private static final int TCP_SERVER_PORT = 1234;
private boolean error = false;
Boolean SocketStarted = false;
protected Void doInBackground(Void... arg0) {
try {
Socket s = new Socket("10.0.2.2", TCP_SERVER_PORT);
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//send output msg
String outMsg = "VER:Android,LAT:28.111921,LNG:-81.950433,ID:1038263,SND:0,VDO:0";
out.write(outMsg);
out.flush();
Log.i("TcpClient", "sent: " + outMsg);
//accept server response
String inMsg = in.readLine() + System.getProperty("line.separator");
Log.i("TcpClient", "received: " + inMsg);
//close connection
} catch (UnknownHostException e) {
error = true;
e.printStackTrace();
} catch (IOException e) {
error = true;
e.printStackTrace();
}
return null;
}
protected void onPostExecute() {
if(error) {
// Something bad happened
}
else {
// Success
}
}
}
//replace runTcpClient() at onCreate with this method if you want to run tcp client as a service
private void runTcpClientAsService() {
Intent lIntent = new Intent(this.getApplicationContext(), TcpClientService.class);
this.startService(lIntent);
}
}

Categories