0

いくつかの画面を備えたアプリがあります。さらに、グローバルに実行されているタイマーがあり、時折(1分ごとに)Webサイトからトランザクションデータを更新してJSONArray(static JSONArray jTransactions)に保存しようとします。

トランザクション画面に移動すると、最初にリストビューにjTransactionsの内容が入力され、表示された情報が数秒ごとに更新されます。ただし、Webスレッドが現在実行されている場合は、すべてに対してnull値を取得します。

私はそれがスレッドの問題であることを知るのに十分なコーダーに精通していますが、それを処理する方法を知るのに十分なJAVA/Android開発の経験がありません。そして、私のグーグルフーは弱いかもしれませんが、私が見つけた唯一の答えは、当てはまらないか、大幅な書き直しを伴うものでした。

私の質問はこれだと思います-アクティビティとフェッチスレッドの間に直接の衝突がないようにコードを変更するにはどうすればよいですか?

また、私のコードがおそらく醜いことを完全に受け入れます。私が言ったように、私はまだプラットフォームを学んでいます。

これが私が実行しているスレッドの簡素化されたバージョンです:

        static int iRefreshTransactions = 30000;
        static boolean bRefreshingTransactions = false;
        static Calendar cLastRefreshTransactions = null;
        final Runnable mRefreshTransactions = new Runnable() {
           public void run() {
               mHandler.removeCallbacks(this);
               Thread T = new tRefreshTransactions();
               T.start();
           }
        };
        private class tRefreshTransactions extends Thread {
            @Override
            public void run() {
            bRefreshingTransactions = true;
            RetrieveTransactions();
                bRefreshingTransactions = false;
                handler.sendEmptyMessage(0);
            }
            private Handler handler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    cLastRefreshTransactions = Calendar.getInstance();
                    ShowToast("cLastRefreshTransactions(): " + cLastRefreshTransactions.getTime().toLocaleString());
                    mHandler.postDelayed(mRefreshTransactions, iRefreshTransactions);
            }
            };
            private Handler failhandler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    // handle the failure somehow
                }
            };
        }

以下は、RetrieveTransactions()コードの簡略化されたバージョンです。

    // Retrieve the user's latest transactions from the website.
    public boolean RetrieveTransactions() {
        String result;
        FailureReason = "";
        iTransactions = 0;

        // Retrieve the Page.
        result = GetPage(Url);

        // Strip the transactions from the page and convert them to a JSONArray.
        try {
            String sTransactions = textExtract(result, "var dataTable1Data=", ";\n", 0);
            jTransactions = new JSONArray(sTransactions);
            iTransactions = jTransactions.length();
            return true;
        } catch (JSONException e1) {
            // Generally if it fails during this, there was no JSONArray to parse (hence no transactions).
            FailureReason = "No Transactions Found";
            return false;
        }
    }

最後に、トランザクションをリストビューに表示する簡略化されたコードを示します。これは、アクティビティの起動時とその後5秒ごとに呼び出されます。

public void ShowTransactions() {
    try {
        if (!bRefreshingTransactions) {
            if (iTransactions==0) {
                return;
            } 
            if (iTransactions==0) return;
            List<String> listContents = new ArrayList<String>(iTransactions);
            for (int i = 0; i < iTransactions; i++) {
                listContents.add(jTransactions.getString(iTransactions - i - 1));
            }
            lvRecentTransactions.setAdapter(new ArrayAdapterTransactions(MyContext, listContents));
        }
    } catch (Exception e) {
        // Do error stuff here
    }
}

前もって感謝します。:)

4

1 に答える 1

2

相互排除の問題のようです。同期jTransactionさせるか、jTransaction変数をsynchonizedブロックに入れます。

  synchronized(jTransactions ){
        String sTransactions = textExtract(result, "var dataTable1Data=", ";\n", 0);
        jTransactions = new JSONArray(sTransactions);
        iTransactions = jTransactions.length();
   }

コードはテストしていませんが、同期がお役に立てば幸いです。

于 2012-07-09T16:46:59.140 に答える