I have a problem in change a text of a textview in android, i'm starting in android, ok I want do a chat with sockets, I made the socket and connected on server but i can't change the text of the textview, ok this is the code:
public class Cliente extends Activity {
Button conect;
Button env;
EditText ip;
EditText nome;
EditText msg;
String nome_txt;
String ip_txt;
Socket cl;
String texto = "";
TextView log;
boolean a = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.start_layout);
conect = (Button) findViewById(R.id.conect);
env = (Button) findViewById(R.id.env);
msg = (EditText) findViewById(R.id.msg);
ip = (EditText) findViewById(R.id.ip_tx);
nome = (EditText) findViewById(R.id.nm_tx);
log = (TextView) findViewById(R.id.log);
conect.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
ip_txt = ip.getText().toString();
nome_txt = nome.getText().toString();
setContentView(R.layout.activity_cliente);
Thread th =new Thread(new Ct());
Log.d("Iniciado", "th");
log.setText("asd");
th.start();
}
});
env.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
try {
envMSG(msg.getText().toString());
msg.setText("");
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
public void envMSG(String msg) throws IOException {
DataOutputStream outToServer = new DataOutputStream(cl.getOutputStream());
outToServer.writeBytes(msg + '\n');
}
public String serOUT() {
try{
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(cl.getInputStream()));
if (inFromServer.ready()) {
String texto = inFromServer.readLine();
return texto;
} else {
return null;
}
}catch(IOException e){
return null;
}
}
public class Ct extends Thread implements Runnable{
#Override
public void run() {
try {
cl = new Socket(ip_txt, 1111);
envMSG(nome_txt);
do{
String tx = serOUT();
if (tx != null) {
texto += tx + "\n";
log.setText(texto);
envMSG("ola");
}
Log.d("Status",cl.isClosed()+"");
this.sleep(10);
}while (true);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Please tell the error reason, and show examples.
Thanks for Reading.
ass.:Lucas Avelino
First of all, you cant set text inside thread, you have to ovveride runOnUiThread method and try to set text in this method.
public class Ct extends Thread implements Runnable{
#Override
public void run() {
try {
cl = new Socket(ip_txt, 1111);
envMSG(nome_txt);
do{
String tx = serOUT();
if (tx != null) {
runOnUiThread(new Runnable() {
#Override
public void run() {
texto += tx + "\n";
log.setText(texto);
envMSG("ola");
}
});
}
Log.d("Status",cl.isClosed()+"");
this.sleep(10);
}while (true);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Related
I have two classes, one is Activity, and one is Thread class:
Activity:
public class MainActivity extends AppCompatActivity {
ObjectInputStream inFromServer = null;
ObjectOutputStream outToServer=null;
Socket clientSocket = null;
String userName;
EditText message;
static TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
message = (EditText)findViewById(R.id.txtMessage);
textView = (TextView)findViewById(R.id.textView);
try {
clientSocket = new Socket("10.0.0.41", 10002);
outToServer =
new ObjectOutputStream(clientSocket.getOutputStream());
inFromServer =
new ObjectInputStream((clientSocket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
ReceiveMessages receiveMessages = new ReceiveMessages(inFromServer);
receiveMessages.start();
}
public void onClickSend(View view) throws IOException {
outToServer.writeObject("Eliran!" + message.getText().toString());
}
public void btnUserName(View view) throws IOException {
EditText editText = (EditText)findViewById(R.id.userName);
userName = editText.getText().toString();
outToServer.writeObject(userName + "!");
}
}
Thread class:
public class ReceiveMessages extends Thread {
ObjectInputStream inFromServer = null;
public ReceiveMessages(ObjectInputStream inFromServer)
{
this.inFromServer = inFromServer;
}
public void run() {
try {
while (true) {
String message = (String) inFromServer.readObject();
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
I want to set text in the text view of the activity in the Thread class.
How can I do it? InflateLayout isn't helping I think.
I would go about it by creating a Callback that gets called when the String is received from the aerver.
interface ReceiveMessageListener {
void onMessageReceived (String message);
}
Then have my Activity implement the interface and set the text in the onMessageReceived call back.
#Override
public void onMessageReceived (String message) {
runOnUiThread(new Runnable() {
#Override
public void run () {
textView.setText(message);
}
});
}
You'll also have to change the constructor for your MessageReceive class to take a MessageReceiveListener.
From your Activity:
ReceiveMessages receive = new ReceiveMessages(input, this);
Only the UI thread can interact with ui elements (such textview). Try using runOnOiThread or mainHandler.post ()
I am trying to access a file twice in my program.
First I am reading from the file, which runs fine.
The second time, I am trying to delete the same file from which I read.
Strangely the second time no records are present in the file. In fact when I try to run the command file.exists it returns false. Why is this happening?
Following is my code:
public class ControlLights extends AppCompatActivity {
private RoomListAdapter adapter;
private List<ROOM> mRoomList;
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.popup,menu);
}
public void filedel(int pos) {
Toast.makeText(getApplicationContext(), String.valueOf(pos), Toast.LENGTH_LONG).show();
File filemain = new File("roomdata.txt");
try {
File temp = File.createTempFile("file",".txt",filemain.getParentFile());
String charset = "UTF-8";
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(temp), charset));
PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(temp), charset));
int p=0;
for(String line; (line=reader.readLine())!=null;) {
if(p == pos) {
line = line.replace(line,"");
writer.println(line);
}
writer.println(line);
}
reader.close();
writer.close();
filemain.delete();
temp.renameTo(filemain);
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
case R.id.Edit:
return true;
case R.id.Delete:
filedel(info.position);
mRoomList.remove(info.position);
adapter.notifyDataSetChanged();
return true;
default:
return super.onContextItemSelected(item);
}
}
public void loadrooms() {
int block = 1024;
try {
boolean exists = (new File("roomdata.txt").exists());
Toast.makeText(getApplicationContext(), String.valueOf(exists), Toast.LENGTH_LONG).show();
FileInputStream fis = openFileInput("roomdata.txt");
InputStreamReader isr = new InputStreamReader(fis);
char[] data = new char[block];
String roomdata = "";
int size;
try {
while ((size = isr.read(data)) > 0) {
String read_data = String.copyValueOf(data, 0, size);
roomdata += read_data;
data = new char[block];
}
} catch (IOException e) {
e.printStackTrace();
}
String[] room_display = roomdata.split("\n");
String[] tempstring;
ListView lsv = (ListView) findViewById(R.id.Room_list);
mRoomList = new ArrayList<>();
for (int b = 0; b < room_display.length; b++) {
tempstring = room_display[b].split(":");
mRoomList.add(new ROOM(tempstring[0], tempstring[1], tempstring[2], tempstring[3], tempstring[4], tempstring[5], tempstring[6], tempstring[7], tempstring[8], tempstring[9]));
}
adapter = new RoomListAdapter(getApplicationContext(), mRoomList);
lsv.setAdapter(adapter);
registerForContextMenu(lsv);
int count = mRoomList.size();
final ArrayList<Integer> disabledpos = new ArrayList<Integer>();
for (int q = 0; q < count; q++) {
ROOM temp_room1 = mRoomList.get(q);
String IP = temp_room1.getRoom_IP_Address();
String online = null;
ConnectionTest CT = new ConnectionTest();
try {
online = CT.execute(IP, "a", "b").get();
Boolean b1 = Boolean.valueOf(online);
if (!b1) {
disabledpos.add(q);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
try {
isr.reset();
isr.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
if (new File("roomdata.txt").delete()) {
Toast.makeText(getApplicationContext(), "deleted", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "not deleted", Toast.LENGTH_LONG).show();
// Not deleted
}
lsv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
int temp_position = position;
Intent p = new Intent(ControlLights.this, Electrical_equipment_list.class);
if (!(disabledpos.contains(position))) {
ROOM temp_room = mRoomList.get(temp_position);
p.putExtra("EE1", temp_room.getEE1());
p.putExtra("EE2", temp_room.getEE2());
p.putExtra("EE3", temp_room.getEE3());
p.putExtra("EE4", temp_room.getEE4());
p.putExtra("EE5", temp_room.getEE5());
p.putExtra("EE6", temp_room.getEE6());
p.putExtra("EE7", temp_room.getEE7());
p.putExtra("EE8", temp_room.getEE8());
p.putExtra("IPaddress", temp_room.getRoom_IP_Address());
startActivity(p);
}
}
});
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_control_lights);
loadrooms();
}
public class ConnectionTest extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
Boolean online;
String tempstring = null;
try {
InetAddress roomaddress = InetAddress.getByName(params[0]);
online = roomaddress.isReachable(100);
tempstring = String.valueOf(online);
} catch (IOException e) {
e.printStackTrace();
}
return tempstring;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
}
}
}
Keep your File as a class' member, since it is an essential component of what the class does
Move your inner logic and file reference initialization to onStart()
public class ControlLights extends AppCompatActivity {
private RoomListAdapter adapter;
private List mRoomList;
private File filemain;
...
public void filedel(int pos) {
Toast.makeText(getApplicationContext(), String.valueOf(pos), Toast.LENGTH_LONG).show();
try {
File temp = File.createTempFile("file",".txt", filemain.getParentFile());
...
}
}
public void loadrooms() {
int block = 1024;
try {
boolean exists = filemain.exists();
...
if (filemain.delete()) {
Toast.makeText(getApplicationContext(), "deleted", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "not deleted", Toast.LENGTH_LONG).show();
// Not deleted
}
} ...
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_control_lights);
}
#Override
protected void onStart() {
super.onStart();
filemain = new File("roomdata.txt");
loadrooms();
}
}
Foot note
I apologize for the horrible code format, but apparently they changed the parsing algorithm to a point where you have to manually type all the code again here instead of just being able to copy-paste it. Anyone being to edit it accordingly is welcome.
I'm trying to select the values of a table on an oracle DataBase and setting the result (the tudo variable) on a TextView, but when I click on the Button on the App, it closes and nothing happen.
public class MainActivity extends ActionBarActivity {
private String tudo = " ";
private TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView)findViewById(R.id.textView);
}
public void onClick(View view){
new Thread(new Runnable() {
#Override
public void run() {
insert();
// textView.setText(select());
}
}).start();
}
protected void select(){
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
String url = "XXXXXXX";
Connection c = DriverManager.getConnection(url, "XXXX", "XXXX");
Statement stmt = c.createStatement();
String teste;
ResultSet rset = stmt.executeQuery("SELECT * FROM TTESTE");
while (rset.next())
{
teste = (" " + rset.getString("NOME") + rset.getInt("ID"));
tudo = tudo + teste;
}
rset.close();
stmt.close();
c.close();
textView.setText(tudo);
}
catch (ClassNotFoundException | SQLException e){
e.printStackTrace();
}
}
}
Use the method:
runOnUiThread(new Runnable() {
#Override
public void run()
{
// seu codigo aqui
});
I have 3 threads and 1 handler in each thread. But it only works one, the other 2 handlers clear the textview completely.
Code:
Thread getServerStatus = new Thread() {
public void run() {
Document doc;
try {
doc = dereference("my url");
String text = doc.select("div#serverstatus").toString();
Message msg = handler_serverstatus.obtainMessage();
msg.obj = text;
handler_serverstatus.sendMessage(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
Handler handler_serverstatus = new Handler()
{
public void handleMessage(Message msg)
{
String text = (String)msg.obj;
TextView tv = (TextView)findViewById(R.id.server_status);
if(text.contains("online")) {
//tv.setTextColor(2);
tv.setText("online");
} else if(text.contains("offline")) {
tv.setText("offline");
} else {
tv.setText("Error #1");
}
}
};
};
Thread getPlayersOnline = new Thread() {
public void run() {
Document doc;
try {
doc = dereference("my url");
String text = doc.select("div#players_on").toString();
Message msg = handler_players.obtainMessage();
msg.obj = text;
handler_players.sendMessage(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
Handler handler_players = new Handler()
{
public void handleMessage(Message msg)
{
String text = (String)msg.obj;
TextView tv = (TextView)findViewById(R.id.players_online);
text = text.replace("<div id=\"players_on\">", "");
text = text.replace("</div>", "");
tv.setText(text);
}
};
};
Thread getPlayersMax = new Thread() {
public void run() {
Document doc;
try {
doc = dereference("url");
String text = doc.select("div#players_max").toString();
Message msg = handler_players_max.obtainMessage();
msg.obj = text;
handler_players_max.sendMessage(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
Handler handler_players_max = new Handler()
{
public void handleMessage(Message msg)
{
String text = (String)msg.obj;
TextView tv = (TextView)findViewById(R.id.players_max);
text = text.replace("<div id=\"players_max\">", "");
text = text.replace("</div>", "");
tv.setText(text);
}
};
};
public void ButtonClick(View view) throws IOException {
getServerStatus.start();
getPlayersOnline.start();
getPlayersMax.start();
}
private Document dereference(String uri) throws IOException {
Connection connection = Jsoup.connect(uri);
return connection.get();
}
Is this maybe totally wrong?
Use
ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(1); // number of working thread
Runnable getServerStatus = new Runnable() {
#Override
public void run() {
Document doc;
try {
doc = dereference("my url");
String text = doc.select("div#serverstatus").toString();
Message msg = handler_serverstatus.obtainMessage();
msg.obj = text;
handler_serverstatus.sendMessage(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
Handler handler_serverstatus = new Handler()
{
public void handleMessage(Message msg)
{
String text = (String)msg.obj;
TextView tv = (TextView)findViewById(R.id.server_status);
if(text.contains("online")) {
//tv.setTextColor(2);
tv.setText("online");
} else if(text.contains("offline")) {
tv.setText("offline");
} else {
tv.setText("Error #1");
}
}
};
};
Runnable getPlayersOnline = new Runnable() {
#Override
public void run() {
Document doc;
try {
doc = dereference("my url");
String text = doc.select("div#players_on").toString();
Message msg = handler_players.obtainMessage();
msg.obj = text;
handler_players.sendMessage(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
Handler handler_players = new Handler()
{
public void handleMessage(Message msg)
{
String text = (String)msg.obj;
TextView tv = (TextView)findViewById(R.id.players_online);
text = text.replace("<div id=\"players_on\">", "");
text = text.replace("</div>", "");
tv.setText(text);
}
};
}
Runnable getPlayersMax = new Runnable() {
public void run() {
Document doc;
try {
doc = dereference("url");
String text = doc.select("div#players_max").toString();
Message msg = handler_players_max.obtainMessage();
msg.obj = text;
handler_players_max.sendMessage(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
Handler handler_players_max = new Handler()
{
public void handleMessage(Message msg)
{
String text = (String)msg.obj;
TextView tv = (TextView)findViewById(R.id.players_max);
text = text.replace("<div id=\"players_max\">", "");
text = text.replace("</div>", "");
tv.setText(text);
}
};
};
newFixedThreadPool.submit(getServerStatus);
newFixedThreadPool.submit(getPlayersOnline);
newFixedThreadPool.submit(getPlayersMax); // submit all your targets
}
public void ButtonClick(View view) throws IOException {
newFixedThreadPool.shutdown();// shutdown and execute it
}
with 3 runnable inside;
Read tutorial about ThreadPools http://www.vogella.com/articles/JavaConcurrency/article.html, http://www.caveofprogramming.com/java/java-multithreading-thread-pools-video-tutorial-part/
or wrap your run() targets with synchronized block{};
Hi and thank you for looking at my question.
I am an intermediate programmer in C but an Android newbie. I have been trying to get a chat programming working. Assuming everything else in the code below works perfectly. The one question I like to ask is when I try to setText() from a thread running, I get an exception above. I looked at many many websites and here too. Found many things, but I really do not understand. Please explain to me in the most simple way or offer me some simple fix if possible.
Thank you very much!!
public class chatter extends Activity {
private String name = "Unknown User";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final EditText msgToServer = (EditText) findViewById(R.id.msgBox);
final EditText chatFromServer = (EditText) findViewById(R.id.chatBox);
final Button MsgToServer = (Button) findViewById(R.id.sendButton);
Socket socket = null;
String ipAddress = "192.168.1.103";
try {
InetAddress serverAddr = InetAddress.getByName(ipAddress);
Socket socketMain = new Socket(serverAddr, 4444);
socket = socketMain;
} catch (IOException e) {
// TODO Auto-generated catch block
Log.e("TCP", "error", e);
}
final OutMsg outMsg = new OutMsg(socket);
Thread msgSenderThread = new Thread(outMsg);
msgSenderThread.start();
//chatFromServer.post(new InMsg(socket, chatFromServer));
Thread msgReceiverThread = new Thread(new InMsg(socket, chatFromServer));
msgReceiverThread.start();
MsgToServer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String msgToServerString;
msgToServerString = msgToServer.getText().toString();
outMsg.message = name + ": " + msgToServerString;
outMsg.readyToSend = true;
msgToServer.setText("");
}
});
}
public void updateResultsInUi (String msg)
{
final EditText chatFromServer = (EditText) findViewById(R.id.chatBox);
chatFromServer.setText(msg);
}
public class InMsg implements Runnable {
Socket socket;
EditText chatFromServer;
public InMsg(Socket socket, EditText chatFromServer)
{
this.socket = socket;
this.chatFromServer = chatFromServer;
}
public void run(){
try {
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str = "FIRSTMESSAGEFROMSERVER";
while (true)
{
if (str.equals("FIRSTMESSAGEFROMSERVER"))
str = in.readLine();
else
str = str + "\n" + in.readLine();
Log.e("TCP", "got the message: " + str);
//Here is where went wrong******************
chatFromServer.setText(str);
//******************************************
}
} catch (IOException e) {
// TODO Auto-generated catch block
Log.e("TCP", "error in receiving", e);
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.setNameMenu:
setname();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void populateChatBox (String msgFromS)
{
Log.e("TCP", "going in to popC");
final EditText textNameInput = (EditText) findViewById(R.id.nameBox);
Log.e("TCP", " popC");
textNameInput.setText(msgFromS);
Log.e("TCP", "going out from popC");
}
public void setname()
{
setContentView(R.layout.custom_dialog);
final EditText textNameInput = (EditText) findViewById(R.id.nameBox);
Button submitNameButton = (Button) findViewById(R.id.submitNameButton);
submitNameButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String nameinput = textNameInput.getText().toString();
if (!name.equals(""))
name = nameinput;
setContentView(R.layout.main);
}
});
}
}
In your run() method:
Message msg = new Message();
String textTochange = "text";
msg.obj = textTochange;
mHandler.sendMessage(msg);
Create the mHandler in your UI thread;
Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
String text = (String)msg.obj;
//call setText here
}
};
You are not on the UI thread when setting the text. You need to be on UI if you want to work on UI items. Create a message handler on the UI thread, post your messages to it and call setText from the handler on the UI thread.
you can do this whenever you are in a thread:
msgToServer.post(new Runnable() {
public void run() {
msgToServer.setText("your text here");
}
}
Your problem is that there are certain interactions that you can only do on the UI thread. This is one of them.
Looks like you might want to use AsyncTask
http://developer.android.com/reference/android/os/AsyncTask.html
Basically you could make your Runnable an AsyncTask instead and do the setText in onProgressUpdate, which gets run on the UIThread.
If you would like to use an AsyncTask to run in the background this is how I would do it:
public class UpdateTextProgress_Task extends AsyncTask<Void,String,Void> {
Socket socket;
EditText chatFromServer;
UpdateTextProgress_Task(EditText chatFromServer, Socket socket){
this.socket = socket;
this.chatFromServer = chatFromServer;
}
#Override
protected Void doInBackground(Void... params) {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str = "FIRSTMESSAGEFROMSERVER";
while(true){
if (str.equals("FIRSTMESSAGEFROMSERVER")){
str = in.readLine();
}
else{
str = str + "\n" + in.readLine();
}
Log.e("TCP", "got the message: " + str);
publishProgress(str); // calls the onProgressUpdate method
}catch (IOException e) {
Log.e("UpdateTextProgress", e.getMessage());
}
return null;
}
#Override
protected void onProgressUpdate(String... progress) {
chatFromServer.setText(progress[0]); //now we are on the UI thread so we can update our EditText
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
Log.e("UpdateTextProgress", "Finished");
}
}
To execute the code:
UpdateTextProgress_Task task = new UpdateTextProgress_Task(chatFromServer,socket);
task.execute();