Я занимаюсь разработкой однорангового чата с использованием программирования сокетов в Android. Номер порта self и IP-адрес и номер порта другого однорангового узла указываются как входные данные, и соединение устанавливается через сокет. Я реализовал чат-активность, используя просмотр списка с помощью специального адаптера, когда чат начинается, после обмена некоторыми сообщениями старое сообщение снова появляется в виде списка, а также порядок отправленных и полученных сообщений портится.
Я распечатал сообщение об обмене в logcat от android studio и, похоже, проблемы нет. Так в чем же причина проблемы? и каким должно быть решение?
Вот чат-активность
public class ChatActivity extends AppCompatActivity {
String ipAddress,portNo;
//public static String message="";
EditText messageTextView;
TextView responseTextView;
static MessageAdapter mAdapter;
ListView message_List;
ArrayList<Message> messageArray;
EditText portText;
int myport;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState != null){
Log.d("STATE",savedInstanceState.toString());
}
setContentView(R.layout.activity_chat);
Bundle bundle = getIntent().getExtras();
if(bundle != null){
String info = bundle.getString("ip&port");
String[] infos = info.split(" ");
ipAddress = infos[0];
portNo = infos[1];
myport = Integer.parseInt(infos[2]);
Log.d("info",ipAddress+" "+portNo+" "+myport);
}
message_List = (ListView) findViewById(R.id.message_list);
messageArray = new ArrayList<Message>();
mAdapter = new MessageAdapter(this, messageArray);
message_List.setAdapter(mAdapter);
messageTextView= (EditText) findViewById(R.id.messageEditText);
//message = messageTextView.getText().toString();
startServer();
}
void startServer(){
Server s = new Server(message_List, messageArray, myport);
s.start();
}
public void sendResponse(View view){
Client c =new Client();
c.execute();
}
public void setView(String s){
String str=responseTextView.getText().toString();
str=str+"\nReceived: "+s;
responseTextView.setText(str);
}
public class Client extends AsyncTask<Void,Void,String> {
String msg = messageTextView.getText().toString();;
@Override
protected String doInBackground(Void... voids) {
try {
String ipadd = ipAddress;
int portr = Integer.parseInt(portNo);
Socket clientSocket = new Socket(ipadd, portr);
OutputStream outToServer =clientSocket.getOutputStream();
PrintWriter output = new PrintWriter(outToServer);
output.println(msg);
output.flush();
clientSocket.close();
}
catch (Exception e) {
e.printStackTrace();
}
return msg;
}
protected void onPostExecute(String result) {
messageArray.add(new Message("Sent: " + result, 0));
message_List.setAdapter(mAdapter);
Log.d("problem","Sent: " + result);
for(Message mssg: messageArray){
String sst = mssg.getMessage();
//Log.d("problem"," "+sst);
}
messageTextView.setText("");
}
}
}
Вот код сервера
public class Server extends Thread {
ListView messageList;
ArrayList<Message> messageArray;
int port;
public Server(ListView messageList, ArrayList<Message> messageArray, int
port) {
this.messageArray = messageArray;
this.messageList = messageList;
this.port = port;
}
ServerSocket welcomeSocket=null;
@Override
public void run(){
try{
String sentence;
welcomeSocket=new ServerSocket(port);
while (true){
Socket connectionSocket=welcomeSocket.accept();
HandleClient c= new HandleClient();
c.execute(connectionSocket);
}
}
catch(Exception e){
e.printStackTrace();
}
}
public class HandleClient extends AsyncTask<Socket,Void,String>{
String sentence;
@Override
protected String doInBackground(Socket... sockets) {
try {
BufferedReader input = new BufferedReader(new
InputStreamReader(sockets[0].getInputStream()));
sentence = input.readLine();
}
catch(Exception e){
e.printStackTrace();
}
return sentence ;
}
protected void onPostExecute(String result) {
messageArray.add(new Message("Received: " + result, 1));
messageList.setAdapter(mAdapter);
Log.d("problem","Received: " + result);
for(Message mssg: messageArray){
String sst = mssg.getMessage();
//Log.d("problem"," "+sst);
}
}
}
}
Вот мой класс адаптера сообщений
public class MessageAdapter extends BaseAdapter{
Context context;
ArrayList<Message> arr = new ArrayList<>();
public MessageAdapter(Context context,ArrayList<Message> arr) {
this.context = context;
this.arr = arr;
for(Message mssg: arr){
String sst = mssg.getMessage();
Log.d("problem"," "+sst);
}
}
@Override
public int getCount() {
return arr.size();
}
@Override
public Object getItem(int i) {
return arr.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int position, View convertView, ViewGroup parent){
//View listItemView=convertView;
if(convertView==null){
convertView=
LayoutInflater.from(context).inflate(R.layout.message_list,parent,false);
}
Message currentMessage= (Message) getItem(position);
String message=currentMessage.getMessage();
//Log.d("problem"," Current Message: " + message);
if(currentMessage.isSent()){
TextView sent=(TextView) convertView.findViewById(R.id.list_sent);
sent.setText(message);
sent.setVisibility(View.VISIBLE);
//sent.setVisibility(View.VISIBLE);
}
else{
TextView received= (TextView)
convertView.findViewById(R.id.list_received);
received.setText(message);
received.setVisibility(View.VISIBLE);
}
return convertView;
}
}