したがって、これにアプローチする方法はたくさんあります。まず、のインスタンスが1つだけ必要なようでConnectToServer
、現在それを渡す必要があるため、そのクラスをシングルトンオブジェクトにしてみてください。これは必須ではなく、スレッドの問題とは何の関係もありませんが、何かのインスタンスが1つしかないことを強制し、それを渡す必要がないようにしたい場合の解決策としてのみ提供します。どこにでも。単純なシングルトン実装は次のようになります。
public class ConnectToServer {
private static ConnectToServer _instance;
/** use this static method to get the one and only instance */
public static ConnectToServer getInstance() {
if (_instance == null) {
_instance = new ConnectToServer();
}
return _instance;
}
/** private to enforce Singleton pattern */
private ConnectToServer() {
}
}
そして、次のように画面で使用します(コンストラクターに渡す必要はありません)。
ConnectoToServer connection = ConnectToServer.getInstance();
connection.blahBlahBlah();
次に、スレッドの問題について説明します。メイン(別名「UI」、別名「イベント」)スレッドでネットワークリクエストを実行するべきではないというのは正しいことです。優れた個別ConnectToServer
のクラスがある場合は、この動作をカプセル化するのが簡単になります。同期 send()
およびメソッドを使用するUIクライアントの代わりにreceiveVector()
、要求を開始するだけの1つのメソッドとConnectToServer
、応答が戻ったときにクラスが呼び出す別のコールバックメソッドを作成します。ConnectToServer
クラスはを使用してこのThread
作業を実行するため、リクエスト中にUIがフリーズすることはありません。
interface
UIクライアントが実装するものを定義します。
public interface RequestListener {
/** listeners must implement this method to get data. method will be called on the UI thread */
void onDataReceived(Vector response);
}
そして、新しい(部分的な)ConnectToServer
クラス:
public class ConnectToServer {
private Thread _worker;
private RequestListener _listener;
public void setRequestListener(RequestListener listener) {
// note: this implementation only allows one listener at once.
// make it a list if you need something more
_listener = listener;
}
/** initiate a network request on a background thread */
public void sendRequest(final String request) {
_worker = new Thread(new Runnable() {
public void run() { // run on the background/worker thread
send(request);
final Vector response = receiveVector();
if (_listener != null) {
// this assumes all our listeners are UI objects, so we pass
// data back to them on the UI thread:
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() { // run on UI thread
_listener.onDataReceived(response);
}
});
}
}
});
_worker.start();
}
}
このクラスでオリジナル send()
とメソッドも作成する必要があることに注意してください。これらは、UIクライアントから直接ではなく、クラス内からのみ呼び出す必要があります。receiveVector()
private
Screen
次に、次のようにクラスをコーディングする必要があります。
public class Screen3 extends MainScreen implements RequestListener {
public Screen3(String exerciseName) {
ConnectToServer connection = ConnectToServer.getInstance();
connection.setRequestListener(this);
// kick off the request (on a background thread)
connection.sendRequest(exerciseName);
}
public void onDataReceived(Vector response) {
if (mylist == null) {
// first time data has been received, so create and add the list field:
mylist = new listField();
add(mylist);
}
mylist.setSize(response.size());
// TODO: presumably, you would copy the contents of 'response' into 'mylist' here
}
}
また、サーバークラスをコーディングして、複数のUIクライアントが同時にリクエストを行うのを防ぎ、現在のリクエストをキャンセルできるようにすることもできます。ただし、上記の方法で、UIをフリーズせずにレスポンシブアプリを提供するソリューションを開始できます。 。