1

私が作成した Android アプリに問題がありますが、実際の電話デバイスで実行した場合にのみ明らかになります。エミュレータでは問題なく動作します。問題が発生するクラスは次のとおりです。

public class JsonServiceHandler {
    private final static String QUEUE_SERVICE_URI = "http://192.168.1.132/QueueTest/AccessService.svc/JSON";

    public static <T extends QueueAccessObject> List<T> GetServiceResult(String serviceMethod, Class<T> classType, Hashtable parameters){
        try
        {
            String url = QUEUE_SERVICE_URI + "/" + serviceMethod;

            if(parameters != null && parameters.size() > 0)
            {
                url += "?";

                Enumeration e = parameters.keys();

                while(e.hasMoreElements())
                {
                    Object key = e.nextElement();
                    url += key.toString() + "=" + parameters.get(key);
                }
            }

            // Send GET request to <service>/<endpoint>
            HttpGet request = new HttpGet(url);
            request.setHeader("Accept", "application/json");
            request.setHeader("Content-type", "application/json");

            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpResponse response = httpClient.execute(request);

            HttpEntity responseEntity = response.getEntity();

            // Read response data into buffer
            char[] buffer = new char[(int)responseEntity.getContentLength()];
            InputStream stream = responseEntity.getContent();
            InputStreamReader reader = new InputStreamReader(stream);
            reader.read(buffer);
            stream.close();

            JSONObject jsobj = new JSONObject(new String(buffer));
            JSONObject ridesResult = jsobj.getJSONObject(serviceMethod + "Result");

            List<T> array = GetObjectsFromJSONArray(ridesResult.getJSONArray("RootResults"), classType);

            return array;
        }
        catch(Exception e){
            return null;
        }
    }

    private static <T extends QueueAccessObject> List<T> GetObjectsFromJSONArray(JSONArray jArray, Class<T> classType) {
        List<T> list = new ArrayList<T>();

        try
        {
            for(int i = 0; i < jArray.length(); ++i){
                T item = classType.getConstructor(JSONObject.class).newInstance(jArray.getJSONObject(i));
                list.add(item);
            }
        }
        catch(Exception ex){}

        return list;                
    }

}

この問題は、HttpGet の JSON 結果を取得し、それを厳密に型指定されたオブジェクトの配列にコピーした後に発生しています。

例外がスローされると、JSON 応答は正常に表示され、厳密に型指定されたオブジェクトのリストが作成され、正常に返されたように見えます。GetObjectsFromJSONArray への呼び出しの割り当てでのみ爆発しList<T> array = GetObjectsFromJSONArray(...ます。

catch ブロック (4 行後) をドロップダウンすると、Eclipse で例外がインスタンス化されているようには見えません。

前述したように、この問題は Android エミュレーターではなく、電話でテストする場合にのみ発生します。また、この問題はデバイス自体で 4 回中 3 回しか発生しないため、一貫して発生するわけではありません。

参考までに、これはすべて AsyncTask 内で行われているため、UI スレッドで Async ネットワーク呼び出しを実行しても問題はありません。

私は Android は初めてで、実際には Java と Eclipse も初めてなので、簡単なことを見落としがちです。

何が起こっているのか、または私の例外が catch ブロックで利用できない理由についてのアイデアはありますか?

4

1 に答える 1

1

ここでスローされている実際の例外があり、最終的にそれを表示しました。インスタンス化されないままになる原因となった問題は、例外自体が Catch ブロックで使用されなかったことのようです (null を返すだけでした)。使用されていない場合、例外パラメーターが作成されないように、Android 環境用のコンパイラの最適化の種類があるのでしょうか?

例外を飲み込むのではなく、実際に例外自体を使用するコードを追加すると、JSONException が返され、応答がストリームの途中で切り捨てられていることがわかりました。もちろん、なぜそれが起こっているのか (デバイス上でのみ) を突き止める必要がありますが、例外のインスタンス化の問題は、使用されていないために削除されていたという事実に関係していました。

編集:

JSONException 自体に関する詳細情報: 明らかに、HttpResponse を JSONObject にロードするために使用していたコードは効果がないか、少なくとも効果に一貫性がありません。

    // Read response data into buffer
    char[] buffer = new char[(int)responseEntity.getContentLength()];
    InputStream stream = responseEntity.getContent();
    InputStreamReader reader = new InputStreamReader(stream);
    reader.read(buffer);
    stream.close();

    JSONObject jsobj = new JSONObject(new String(buffer));

ここにある convertStreamToString メソッドの内容に優先して、このコードを削除しました。それは私を転がしました。

于 2012-12-03T23:21:46.760 に答える