0

ListFieldコントロールを使用して、xmlWebサービスから返されたデータを表示しています。ListFieldまたは画面を毎分更新して、ListFieldを新しいレコードまたはデータで更新したいと思います。

以下のコードを使用してみましたが、正しく機能していません(ハングしています)。

public MyApp() {
    // Push a screen onto the UI stack for rendering.
    UiApplication.getUiApplication().invokeLater(new Runnable() {
        public void run() {
            UiApplication.getUiApplication().pushScreen(new MyScreen());
        }
    },5000,true);
}
ResponseHandler handler = new ResponseHandler();
ListField listUsers = new ListField(handler.getItem().size());

public MyScreen() {
    setTitle("yQAforum");
    //Fetch the xml from the web service
    String wsReturnString = GlobalV.Fetch_Webservice("myDs");
    //Parse returned xml
    SAXParserImpl saxparser = new SAXParserImpl();
    ByteArrayInputStream stream = new ByteArrayInputStream(wsReturnString.getBytes());
    try {
        saxparser.parse( stream, handler );
    } 
    catch ( Exception e ) {
        response.setText( "Unable to parse response.");
    }
    //Return vector sze from the handler class
    listUsers.setSize(handler.getItem().size());
    listUsers.setCallback(this);
    listUsers.setEmptyString("No Users found", 0);
    add(listUsers);
}
4

1 に答える 1

2

UIスレッドでWebサービスからデータをフェッチしようとしています。それはほとんどの場合間違ったことです。

UIスレッド(メインスレッドとも呼ばれます)は、UIの描画、タッチなどのユーザーアクションの追跡、またはトラックパッド/トラックボールを介したナビゲーションを担当します。リモートWebサーバーが応答するのを待ってUIスレッドがブロックされている場合、UIを処理できません。

行う必要のある変更がいくつかあります。

public MyApp() {
    // Push a screen onto the UI stack for rendering.
    UiApplication.getUiApplication().invokeLater(new Runnable() {
        public void run() {
            UiApplication.getUiApplication().pushScreen(new MyScreen());
        }
    },5000,true);
}

に変更する必要があります

public MyApp() {
    // Push a screen onto the UI stack for rendering.
    pushScreen(new MyScreen());
}

コンストラクターはMyApp()すでにUIスレッドで呼び出されているため、UIスレッドで呼び出しinvokeLater()を実行するためにを使用する必要はありませんpushScreen()MyAppコンストラクター内から実行した場合、UIスレッドで既に呼び出されます。また、5000ミリ秒の遅延はあまり役に立ちません。これにより、アプリの起動が5秒遅れるだけで、ユーザーはこれを嫌います。

スプラッシュ画面などを実装しようとしている場合は、アプリの起動時にスタックオーバーフローで「BlackBerryスプラッシュ画面」を検索してください。結果が見つかるはずです。

これで、クラスが作成されたら、UIスレッドからWebサービスの結果をフェッチしないMyScreenように注意する必要があります。コンストラクターはUIスレッドで実行されます。必要に応じて、画面が表示されたら、バックグラウンドスレッドでWebサービスリクエストを開始できます。そのための1つの方法は、次を使用することです。MyScreenonUiEngineAttached()

protected void onUiEngineAttached(boolean attached) {
    if (attached) {
        // TODO: you might want to show some sort of animated
        //  progress UI here, so the user knows you are fetching data

        Timer timer = new Timer();
        // schedule the web service task to run every minute
        timer.schedule(new WebServiceTask(), 0, 60*1000);
    }
}

public MyScreen() {
    setTitle("yQAforum");

    listUsers.setEmptyString("No Users found", 0);
    listUsers.setCallback(this);
    add(listUsers);
}

private class WebServiceTask extends TimerTask {
    public void run() {
        //Fetch the xml from the web service
        String wsReturnString = GlobalV.Fetch_Webservice("myDs");
        //Parse returned xml
        SAXParserImpl saxparser = new SAXParserImpl();
        ByteArrayInputStream stream = new ByteArrayInputStream(wsReturnString.getBytes());
        try {
           saxparser.parse( stream, handler );
        } 
        catch ( Exception e ) {
           response.setText( "Unable to parse response.");
        }
        // now, update the UI back on the UI thread:
        UiApplication.getUiApplication().invokeLater(new Runnable() {
           public void run() {
              // TODO: record the currently selected, or focused, row

              //Return vector sze from the handler class
              listUsers.setSize(handler.getItem().size());
              // Note: if you don't see the list content update, you might need to call
              //   listUsers.invalidate();
              // here to force a refresh.  I can't remember if calling setSize() is enough.

              // TODO: set the previously selected, or focused, row
           }
        });
    }
}

Webサービスが応答しない場合、または1分以上かかる場合に備えて、エラー処理を追加する必要があります(最後のリクエストが終了していなければ、新しいリクエストを作成したくないでしょう)。

しかし、これで始められるはずです。

注: UIスレッドでネットワークコードを実行する際の問題を修正しても、コードが機能しない場合がありますWebサービスデータのフェッチで問題が発生する可能性があります。それをデバッグする必要があります。投稿されたコードに関する問題を1つだけ示しています。それでもWebサービスのフェッチに問題がある場合は、別の質問を投稿してください(UIスレッドの問題は修正されています)。ありがとう。

于 2012-12-27T21:46:39.403 に答える