簡體   English   中英

為什么線程中的公共方法無法在onCreate中解析?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM