[英]Why does a public method in a thread not resolve in onCreate?
應用程序概述:一種更簡單的服務器,在端口上偵聽連接。 對於每個連接到該端口的客戶端,當它們從GPS芯片中出來時,它將發送GPS NMEA字符串。
因此,onCreate啟動了一個偵聽該端口的新線程。 對於每個連接,此偵聽器線程都會衍生出另一個新線程。 這些線程中的每一個當前僅每兩秒發出一次“仍然連接”消息。 這部分工作正常,我可以建立幾個telnet會話並進行連接,一切都按預期進行。 所有位置信息也在此代碼中起作用; 它會使用正確且不斷變化的GPS信息正確更新屏幕。
我想注冊一個Nmealistener,然后讓它將該字符串分派給服務連接的每個線程。 但是,socketListenerThread.MasterDispatchNmeaMessage(nmea)不會在addNmeaListener內部解析。 (它也不會解決它的外部問題。)addNmeaListener似乎沒有問題,如果我只是通過Log.d轉儲消息,它將很樂意這樣做。
在socketListenerThread類中,方法MasterDispatchNmeaMessage也被標記為“從未調用”。
那么,是什么導致MasterDispatchNmeaMessage無法解決?
對於不熟悉的人,示例NMEA字符串如下所示:
$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47
它們是連發的,可能在我正在測試的Samsung S4上平均每秒五到十行。
附加說明:我的目標是API22。此外,位置類還需要進行更多權限檢查。 因此,在添加新的權限檢查以使其與最新的庫兼容之前,我想使所有這些實際上都起作用。
public class ActivityMain extends AppCompatActivity implements LocationListener {
static final String TAG = "GPSOverWiFi";
static final int LISTENING_PORT = 8085;
private TextView latitudeField;
private TextView longitudeField;
private LocationManager locationManager;
private String provider;
Thread socketListenerThread;
TextView info, infoip;
ServerSocket serverSocket;
int gConnectionCount = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
latitudeField = (TextView) findViewById(R.id.liveLatitude);
longitudeField = (TextView) findViewById(R.id.liveLongitude);
infoip = (TextView) findViewById(R.id.infoip);
info = (TextView) findViewById(R.id.info);
// Get the GPS location manager
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, false);
Location location = locationManager.getLastKnownLocation(provider);
// Initialize the location fields
if (location != null) {
System.out.println("Provider " + provider + " has been selected.");
onLocationChanged(location);
} else {
latitudeField.setText("Location not available");
longitudeField.setText("Location not available");
}
infoip.setText("IP Addresss: " + getIpAddress() + ":" + LISTENING_PORT);
socketListenerThread = new SocketListenerThread();
socketListenerThread.start();
//for giggles, it doesn't resolve here either, but this it needs to resolve a few lines down...
//socketListenerThread.MasterDispatchNmeaMessage("asdf");
locationManager.addNmeaListener(new GpsStatus.NmeaListener() {
public void onNmeaReceived(long timestamp, String nmea) {
// ////////////////////////////////////////////////////////////
// socketListenerThread.MasterDispatchNmeaMessage errors here with 'can't resolve
// ////////////////////////////////////////////////////////////
socketListenerThread.MasterDispatchNmeaMessage(nmea);
Log.d(TAG, "NMEA: " + nmea);
}
});
}
public class SocketListenerThread extends Thread {
Socket socket;
ArrayList<EachConnectionThread> connectionThreads = new ArrayList<EachConnectionThread>();
public void run() {
try {
serverSocket = new ServerSocket(LISTENING_PORT);
while (!isInterrupted()) { //You should handle interrupts in some way, so that the thread won't keep on forever if you exit the app.
socket = serverSocket.accept();
gConnectionCount++;
EachConnectionThread thread = new EachConnectionThread(socket);
connectionThreads.add(thread);
thread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void MasterDispatchNmeaMessage(String nmeaMessage) {
for (EachConnectionThread serverThread : connectionThreads)
serverThread.dispatchNmeaMessage(nmeaMessage);
}
}
public class EachConnectionThread extends Thread {
private Socket hostThreadSocket;
EachConnectionThread(Socket socket) {
hostThreadSocket = socket;
}
PrintStream printStream;
@Override
public void run() {
try {
OutputStream outputStream;
outputStream = hostThreadSocket.getOutputStream();
printStream = new PrintStream(outputStream);
printStream.print("Connected\r\n");
while(!printStream.checkError()) {
SystemClock.sleep(2000);
printStream.print("Still connected\r\n");
}
printStream.close();
outputStream.close();
hostThreadSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
gConnectionCount--;
}
public void dispatchNmeaMessage(String nmeaString){
printStream.print(nmeaString);
}
}
更改成員變量聲明
Thread socketListenerThread;
至
SocketListenerThread socketListenerThread;
因此您可以通過socketListenerThread
實例訪問SocketListenerThread
方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.