0

我有一个带有多个屏幕的应用程序。此外,我有一个全局运行的计时器,它偶尔(每分钟左右)尝试从网站刷新他们的交易数据并将其存储在 JSONArray ( static JSONArray jTransactions) 中。

当你进入 Transaction 屏幕时,它做的第一件事就是用 jTransactions 的内容填充 ListView,它会每隔几秒刷新一次显示的信息。但是,如果 web 线程当前正在运行,我会得到所有内容的空值。

我有足够的编码能力,知道这是一个线程问题,但我对 JAVA/Android 开发的经验不足,不知道如何处理它。而且我的 Google-fu 可能很弱,但我发现的唯一答案要么不适用,要么涉及大量重写。

我想我的问题是——我怎样才能改变我的代码,以便我的活动和获取线程之间没有直接冲突?

我也完全接受我的代码可能很丑;正如我所说,我还在学习这个平台。

这是我正在运行的线程的精简版本:

        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 回答