Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Java: Järkevä tapa datan vastaanottamiseen

Macro [07.02.2013 18:14:55]

#

Javalla olen työstänyt ohjelmaa, joka puhelimesta Bluetoothin yli hakee dataa, kuten tekstiviestejä ja yhteystietoja. Nykyinen toteutus vastaanottaa kaiken mitä puhelimelta lähetetään ja se tulostetaan

@Override
public void run() {
    try {
        this.localDevice = LocalDevice.getLocalDevice();
        this.localDevice.setDiscoverable(DiscoveryAgent.GIAC);

        this.server = (StreamConnectionNotifier) Connector.open(URL);

        while(true) {
            if(this.connection == null) {
                this.connection = this.server.acceptAndOpen();

                System.out.println("INFO: Bluetooth client connected");

                BufferedReader reader = new BufferedReader(new InputStreamReader(connection.openInputStream()));
                this.writer = new BufferedWriter(new OutputStreamWriter(connection.openOutputStream()));

                String line;
                while((line = reader.readLine()) != null) {
                    if(line.equals("--#do:disconnect")) {
                        break;
                    }

                    System.out.println("INFO: Received from Bluetooth: " + line);
                }

                System.out.println("INFO: Client disconnected");
            }
        }
    } catch(BluetoothStateException ex) {
        ex.printStackTrace();
    } catch(IOException ex) {
        ex.printStackTrace();
    }
}

Nyt tämä silmukka hakee kaiken datan, mitä Bluetoothin kautta vastaanotetaan. Luokkaan tarvitsisi tehdä metodi getContacts(), joka hakisi puhelimeta yhteystiedot ja palauttaisi listan niistä. Ongelmana on, että miten saan ne tiedot poimittua kun silmukka niitä vastaanottaa ja tulostelee.

Miten luokkaan olisi järkevä toteuttaa metodeja, jotka voivat tarvittaessa vastaanottaa datan ja jatkokäsitellä sen?

Metabolix [07.02.2013 21:03:16]

#

Jos puhelin vain vastaa järjestyksessä pyyntöihin, jotka sille on erikseen lähetetty, on tietysti yksinkertaisinta lukea vastaus heti pyynnön jälkeen.

Jos puhelin lähettää tiedot pyytämättä ja yllätyksenä, pitää vain tunnistaa tuossa silmukassa tiedon tyyppi ja kutsua sitten oikeaa metodia, joka osaa lukea virrasta loput samaan viestiin tiedot. Tämän voi toteuttaa lukuisilla if-lauseilla tai kokeilemalla eri käsittelijöitä silmukassa tai hakemalla oikean käsittelijän suoraan Map-rakenteesta viestin alun perusteella.

while ((line = reader.readLine()) != null) {
	// A:
	if (line.equals("--foo")) {
		handleFoo(reader);
	}

	// B:
	// List<Handler> handlers;
	// handlers.add(new FooHandler());
	for (Handler h: handlers) {
		if (h.canHandle(line)) {
			h.handle(line, reader);
			break;
		}
	}

	// C:
	// Map<String, Handler> handlers;
	// handlers.put("--foo", new FooHandler());
	if (handlers.containsKey(line)) {
		handlers.get(line).handle(line, reader);
	}
}

Metabolix [08.02.2013 18:00:03]

#

Mietin viestiäsi uudelleen ja huomasin, että kysymyksesi ehkä koskikin tiedon välittämistä silmukasta getContacts-metodille. Voit käyttää yksinkertaisesti muuttujia, synkronointia ja wait- ja notify-metodeja.

public FooData getFoo() throws InterruptedException {
	// Haetaan käsittelijä; ks. edellisen viestin Map-vaihtoehto.
	FooHandler fooHandler = (FooHandler) handlers.get("--foo");
	// Synkronoidaan käsittelijän suhteen; ks. käsittelijän osuus jäljempänä.
	synchronized(fooHandler) {
		// Lähetetään pyyntö.
		writer.write("--get-foo\n");
		// Odotetaan, että käsittelijä saa vastauksen.
		fooHandler.wait();
		// Palautetaan käsittelijän saama data.
		return fooHandler.data;
	}
}

public class FooHandler implements BluetoothResponseHandler {
	public FooData data;

	// Synkronoidaan tämän käsittelijän suhteen.
	// Synkronoinnin tarkoitus on, että lukusilmukka ei pysty kutsumaan
	// handle-metodia kesken getFoo-metodin suorituksen paitsi wait-rivillä.
	synchronized public void handle(String line, BufferedReader reader) {
		// Luetaan vastaus. (TODO)
		data = new FooData();
		// Ilmoitetaan odottajalle, että vastaus on saapunut.
		notify();
	}
}

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta