使用循环解析从android sqlite到远程数据库的列表


Parsing a list from android sqlite to remote database using a loop

我正在构建的部分android应用程序需要我在sqlite数据库中保存用户列表。然后,用户可以输入一个活动,该活动显示当前存储在listview中的sqlite数据库中的用户列表。

然后我尝试实现一个函数来同步这个用户列表到远程数据库,使用Async任务,JSON和PHP服务,通过使用FOR LOOP循环通过数据库表'users'

问题是同步只对列表中的第一个项目有效。将此消息传递给远程数据库后,该活动将崩溃。日志显示:

E/JSON Parser: Error parsing data org.json.JSONException:类型为java.lang.String的值数据不能转换为JSONObject

E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #3进程:example.prguru.com.pi_prototype_30, PID: 5139java.lang.RuntimeException:执行doInBackground()时发生错误android.os.AsyncTask做3.美元(AsyncTask.java: 304)…

由:java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法'java.lang.String org.json.JSONObject.toString()'引起example.prguru.com.pi_prototype_30.ShowAdmins syncUser.doInBackground美元(ShowAdmins.java: 137)example.prguru.com.pi_prototype_30.ShowAdmins syncUser.doInBackground美元(ShowAdmins.java: 87)

java代码中的第137行是:

 Log.d("Sync Attempt", jobj.toString());
PHP代码:

require_once 'config.php';
if(!empty($_POST)){
$row = $_POST['table_id'];
$type = $_POST['type'];
$id_num = $_POST['id_number'];
$name = $_POST['name'];
$email  = $_POST['email'];
$course = $_POST['course'];
$password = $_REQUEST['password'];
$ins = mysql_query("INSERT INTO pi_prototype_inventory_30.users (table_id, type, id_number, name, email, course, password) 
VALUES('$row','$type','$id_num','$name', '$email', '$course', '$password')");
if(!$ins)
{
    echo (mysql_error());
}
else
{
    echo ("data inserted");
}
}
else {
echo (mysql_error());
}

SYNC CLASS:

    @Override
    protected String doInBackground(String... args) {
        // TODO Auto-generated method stub
        // Check for success tag
        int success;
        DBHandler dbAdapter = DBHandler.getDBHandlerInstance(getApplicationContext());
        try {
            dbAdapter.createDataBase();
        } catch (IOException e) {
            Log.i("*** select ", e.getMessage());
        }
        dbAdapter.openDataBase();
        String query = "SELECT * FROM users";
        ArrayList<ArrayList<String>> stringList = dbAdapter.selectRecordsFromDBList(query, null);
        dbAdapter.close();
        try {
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(7);
            for (int i = 0; i < stringList.size(); i++) {
                ArrayList<String> list = stringList.get(i);
                nameValuePairs.add(new BasicNameValuePair("table_id", list.get(0)));
                nameValuePairs.add(new BasicNameValuePair("type", list.get(1)));
                nameValuePairs.add(new BasicNameValuePair("id_number", list.get(2)));
                nameValuePairs.add(new BasicNameValuePair("name", list.get(3)));
                nameValuePairs.add(new BasicNameValuePair("email", list.get(4)));
                nameValuePairs.add(new BasicNameValuePair("course", list.get(5)));
                nameValuePairs.add(new BasicNameValuePair("password", list.get(6)));
                Log.d("Request!", "Starting!");
                jobj = jsonParser.makeObjHttpRequest(REG_URL, "POST", nameValuePairs);
                Log.d("Sync Attempt", jobj.toString());
            }//forLoop
                success = jobj.getInt(TAG_SUCCESS);
                if (success == 1){
                    Log.d("SYNCED!", jobj.toString());
                    return jobj.getString(TAG_MESSAGE);
                }
                else {
                    Log.d("Sync failure!", jobj.getString(TAG_MESSAGE));
                    return jobj.getString(TAG_MESSAGE);
                }

        } catch (JSONException e){
            e.printStackTrace();
        }
        return null;
    }//doInBackground

JSON PARSER CLASS:

public JSONObject makeObjHttpRequest(String url, String method,
                                  List<NameValuePair> params) {
    // Making HTTP request
    try {
        // check for request method
        if(method.equals("POST")){
            // request method is POST
            // defaultHttpClient
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);
            httpPost.setEntity(new UrlEncodedFormEntity(params));
            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            is = httpEntity.getContent();
        }else if(method.equals("GET")){
            // request method is GET
            DefaultHttpClient httpClient = new DefaultHttpClient();
            String paramString = URLEncodedUtils.format(params, "utf-8");
            url += "?" + paramString;
            HttpGet httpGet = new HttpGet(url);
            HttpResponse httpResponse = httpClient.execute(httpGet);
            HttpEntity httpEntity = httpResponse.getEntity();
            is = httpEntity.getContent();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                is, "iso-8859-1"), 8);
        StringBuilder sb = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            sb.append(line).append("'n");
        }
        is.close();
        json = sb.toString();
    } catch (Exception e) {
        Log.e("Buffer Error", "Error converting result " + e.toString());
    }
    // try parse the string to a JSON object
    try {
        Log.i("tagconvertstr", "["+json+"]");
        jObj = new JSONObject(json);
    } catch (JSONException e) {
        Log.e("JSON Parser", "Error parsing data " + e.toString());
    }
    // return JSON String
    return jObj;
}

我是否需要在PHP代码中实现某种循环,以便它接受列表中的多个条目?我不知道该如何编写代码,因为我永远无法确定在任何时候需要同步多少条目。还是问题出在java代码本身?我不太确定如何理解日志中出现的错误

您的解析器返回一个空对象。Logcat对此非常清楚。第一个消息是:

E/JSON Parser﹕ Error parsing data org.json.JSONException: Value data of type java.lang.String cannot be converted to JSONObject

这与解析器中的catch块中的内容完全匹配:

try {
    Log.i("tagconvertstr", "["+json+"]");
    jObj = new JSONObject(json);
} catch (JSONException e) {
    Log.e("JSON Parser", "Error parsing data " + e.toString()); // <- HERE
}

如果在此块中抛出异常,则不会分配jObj。如果您希望解析器永远不返回null,那么您需要在catch块中分配jObj。否则,您的其他代码需要在尝试使用它之前检查返回的值是否为空。