1

私はブラックベリー開発に不慣れで、ネイティブブラックベリーアプリケーションを作成しています。アプリケーションのすべての画面で、同じ接続でサーバーとデータを送受信する必要があります。

これまでに行ったことはConnectToServer、送受信するためのメソッドがたくさんあるクラスを作成したことです。メイン画面でインスタンス化し、パラメータとして各画面に渡します。

ユーザーが情報を入力してボタンを押したときにのみ読み取りと書き込みを行うため、そのクラスはスレッドではありません。つまり、基本的に、私が聞いたイベントスレッドでinputStreamとoutputStreamを使用しているのはBADです。ConnectToServer次に、サーバーが送信したものを取得するように依頼します。たとえば、ListFieldの作成に使用するベクトルを取得します。

これらのUIを更新するにはどうすればよいですか?

public class Screen3 extends MainScreen {

  ConnectToServer con;
  Vector v;

  public Screen3(String exerciseName, ConnectToServer connect)
  {
      con = connect;
      con.send(exerciseName);
      v = con.receiveVector();

      mylist = new listField();
      mylist.setSize(v.size());
      add(mylist);
   }

   public void drawListRow(...)
   {
      graphics.drawText((String) v.elementAt(index)
   }
}
4

1 に答える 1

0

したがって、これにアプローチする方法はたくさんあります。まず、のインスタンスが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がフリーズすることはありません。

interfaceUIクライアントが実装するものを定義します。

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をフリーズせずにレスポンシブアプリを提供するソリューションを開始できます。 。

于 2012-09-14T21:53:40.007 に答える