【发布时间】:2023-03-05 10:55:01
【问题描述】:
我在 Android Studio 上编写了一段代码,用于从套接字服务器接收图像,并且每次单击按钮时应用程序都会连接到服务器。
但是,当我运行应用程序并单击按钮时,什么都没有显示,但服务器会发送一条消息说照片已发送。当我再次单击按钮时,第二次(服务器未连接)图像立即弹出。
我认为问题在于当我单击一次按钮时线程并没有完全关闭,但是如果我再次单击它,线程会强制关闭并启动一个新线程以显示图像。
主要活动java文件的代码是:
package com.example.myapplication;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.Socket;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private TextView mTextViewReplyFromServer;
private EditText mEditTextSendMessage;
private ImageView mImg;
private byte [] imgbyte;
Handler updateConversationHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button buttonSend = (Button) findViewById(R.id.btn_send);
mEditTextSendMessage = (EditText) findViewById(R.id.edt_send_message);
mTextViewReplyFromServer = (TextView) findViewById(R.id.tv_reply_from_server);
mImg = (ImageView)findViewById(R.id.imageView);
String filepath = "/sdcard/DCIM/img.jpeg";
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_send:
Thread fst = new Thread(new ServerThread());
fst.start();
break;
}
}
public class ServerThread implements Runnable {
byte [] line;
Bitmap bitmap;
public void run() {
try {
Socket client = new Socket("192.168.1.145", 5560);
while (true) {
// LISTEN FOR INCOMING CLIENTS
try {
int bytesRead;
int current = 0;
int filesize=215320;
byte [] mybytearray2 = new byte [filesize];
InputStream is = client.getInputStream();
FileOutputStream fos = new FileOutputStream("/sdcard/DCIM/img.jpg"); // destination path and name of file
//FileOutputStream fos = new FileOutputStream("/storage/sdcard0/Pictures/Screenshots/");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray2,0,mybytearray2.length);
current = bytesRead;
do {
bytesRead =
is.read(mybytearray2, current, (mybytearray2.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
bos.write(mybytearray2, 0 , current);
bos.flush();
// bitmap = BitmapFactory.decodeByteArray(mybytearray2 , 0, mybytearray2.length);
// mImg.setImageBitmap(bitmap);
//System.out.println(end-start);
updateConversationHandler.post(new updateUIThread(mybytearray2));
bos.close();
client.close();
break;
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class updateUIThread implements Runnable {
private byte[] byteArray;//private String msg;
public updateUIThread(byte[] array){ //public updateUIThread(String str) {
this.byteArray=array; //this.msg = str;
}
@Override
public void run() {
Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray , 0, byteArray .length);
mImg.setImageBitmap(bitmap);//text.setText(text.getText().toString()+"Client Says: "+ msg + "\n");
}
}
}
有没有办法在收到图片后立即终止线程?
我的图像也显示在 android 模拟器上,但没有显示在我的手机上。这可能是什么原因?
编辑:如果我在 oncreate 部分启动线程,图像会在应用程序启动后立即弹出
编辑:python 服务器代码:
import socket
from time import sleep
from time import time
host = ''
port = 5560
filePath = "/media/pi/ESD-USB/image.jpg"
def setupServer():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("Socket created.")
try:
s.bind((host, port))
except socket.error as msg:
print(msg)
print("Socket bind comlete.")
return s
def setupConnection():
s.listen(1) # Allows one connection at a time.
conn, address = s.accept()
print("Connected to: " + address[0] + ":" + str(address[1]))
return conn
def sendPic(s, filePath):
print(filePath)
pic = open(filePath, 'rb')
chunk = pic.read()
size = len(chunk)
print (size)
t = time()
print("Sending Picture")
s.sendall(chunk)
pic.close()
print("Done sending")
print("Elapsed time = " + str(time() - t) + 's')
s.close()
return "Done sending"
def backup(filePath):
conn = setupConnection()
response = sendPic(conn, filePath)
return response
s = setupServer()
while True:
print(filePath)
backup(filePath)
print("Everything should be backed up now.")
break
【问题讨论】:
-
to receive images from a socket serverANDthe server sends a message saying the photo is received不匹配。 -
@blackapps 我的错,服务器说照片已发送。
-
but the server sends a message saying the photo is sent.服务器将该消息发送给谁?给你的客户?接收该消息的代码在哪里? -
mImg.setImageBitmap(bitmap);不能在线程的run()中设置ui。 -
为什么要使用处理程序和可运行程序来打印堆栈跟踪?没有意义。只需打印它们。