【问题标题】:HTTP POST successful, but the AsyncTask returning NullPointerException?HTTP POST 成功,但 AsyncTask 返回 NullPointerException?
【发布时间】:2011-07-27 10:07:29
【问题描述】:

我的 Android 应用程序中有输入表单 输入的数据将保存到在线数据库中

现在我可以使用 AsyncTask 保存数据并上传图片了。

数据上传成功,但是AsyncTask返回java.lang.NullPointerException

这是我的 AsyncTask 类:

private class SaveAsetData extends AsyncTask<String, Void, String>{

    ProgressDialog pd = new ProgressDialog(FormAsetTambah.this);

    BufferedReader in = null;

    final TextView errorText = (TextView) findViewById(R.id.error_text);

    protected void onPreExecute(){
        pd.setMessage(Functions.GetString(getApplicationContext(), R.string.progress_dialog_loading));
        pd.show();
    }

    @Override
    protected String doInBackground(String... arg0) {

        try {

            String URL_DESTINATION = URLVariables.get_base_url()+"aset_tambah_pic.php";

            Bitmap bm = BitmapFactory.decodeFile(arg0[7]);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            bm.compress(CompressFormat.JPEG, 50, bos);

            HttpClient httpClient = CustomHttpClient.getHttpClient();
            HttpPost postRequest = new HttpPost(URL_DESTINATION);           

            MultipartEntity reqEntity = new MultipartEntity(
            HttpMultipartMode.BROWSER_COMPATIBLE);
            reqEntity.addPart("uploadedfile", new FileBody(new File(arg0[7])));
            reqEntity.addPart("nama", new StringBody(arg0[0]));
            reqEntity.addPart("detail", new StringBody(arg0[1]));
            reqEntity.addPart("keterangan", new StringBody(arg0[2]));
            reqEntity.addPart("longitude", new StringBody(arg0[3]));
            reqEntity.addPart("latitude", new StringBody(arg0[4]));
            reqEntity.addPart("kategori", new StringBody(arg0[5]));
            reqEntity.addPart("daerah", new StringBody(arg0[6]));
            postRequest.setEntity(reqEntity);

            HttpResponse response = httpClient.execute(postRequest);

            in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));

            StringBuffer sb = new StringBuffer("");
            String line = "";
            String NL = System.getProperty("line.separator");

            while((line = in.readLine()) != null){
                sb.append(line+NL);
            }

            in.close();

            String result = sb.toString();

            return result;

        }catch(Exception e){            
            return e.toString();
        }

    }

    protected void onPostExecute(String result){

        try{

            String output = result.toString().trim();
            error_text.setText(output);

            if(output.equals("1")){
                Functions.MakeToast(getApplicationContext(), ERR_SAVED);
                Intent daftarAset = new Intent(getApplicationContext(), DaftarAset.class);
                startActivity(daftarAset);
                finish();
            }else if(output.equals("2")){
                Functions.MakeToast(getApplicationContext(), ERR_QUERY);
            }else{
                Functions.MakeToast(getApplicationContext(), ERR_HTTPFAIL);
            }

        }catch(Exception e){
            Functions.MakeToast(getApplicationContext(), "onPostExecute fail : "+e.toString()); // it failed here
        }
        pd.dismiss();
    }

}

你知道我的错在哪里吗? 或任何建议/解决方案使它变得更好?

更新

这是我在 logcat 上的例外情况

07-27 21:54:09.222: WARN/System.err(17600): java.lang.NullPointerException
07-27 21:54:09.222: WARN/System.err(17600):     at com.ngimagrid.nigmago.FormAsetTambah$SaveData.onPostExecute(FormAsetTambah.java:567)
07-27 21:54:09.222: WARN/System.err(17600):     at com.ngimagrid.nigmago.FormAsetTambah$SaveData.onPostExecute(FormAsetTambah.java:1)
07-27 21:54:09.222: WARN/System.err(17600):     at android.os.AsyncTask.finish(AsyncTask.java:417)
07-27 21:54:09.222: WARN/System.err(17600):     at android.os.AsyncTask.access$300(AsyncTask.java:127)
07-27 21:54:09.222: WARN/System.err(17600):     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429)
07-27 21:54:09.222: WARN/System.err(17600):     at android.os.Handler.dispatchMessage(Handler.java:99)
07-27 21:54:09.222: WARN/System.err(17600):     at android.os.Looper.loop(Looper.java:123)
07-27 21:54:09.222: WARN/System.err(17600):     at android.app.ActivityThread.main(ActivityThread.java:3687)
07-27 21:54:09.222: WARN/System.err(17600):     at java.lang.reflect.Method.invokeNative(Native Method)
07-27 21:54:09.222: WARN/System.err(17600):     at java.lang.reflect.Method.invoke(Method.java:507)
07-27 21:54:09.222: WARN/System.err(17600):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
07-27 21:54:09.222: WARN/System.err(17600):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
07-27 21:54:09.222: WARN/System.err(17600):     at dalvik.system.NativeStart.main(Native Method)

更新

这是我的服务器端代码:

<?php

    require_once("functions.php");

    $nama = trim($_POST['nama']);
    $detail = trim($_POST['detail']);
    $keterangan = trim($_POST['keterangan']);
    $longitude= trim($_POST['longitude']);
    $latitude = trim($_POST['latitude']);

    $kategori = trim($_POST['kategori']);
    $daerah = trim($_POST['daerah']);

    $target_path = "images/";
    $file_tmp_name = $_FILES['uploadedfile']['tmp_name'];
    $file_name = str_replace(array(" ","-"), "_", strtolower(basename($_FILES['uploadedfile']['name'])));
    $target_path = $target_path.$file_name; 


    if(empty($nama) || empty($detail) || empty($keterangan) || empty($longitude) || empty($latitude) || empty($kategori) || empty($daerah) || empty($file_tmp_name)){

        echo "5";

    }else{

        openDB();

        $get_id_kategori = mysql_fetch_array(mysql_query("SELECT `id_kategori` FROM `aset_kategori` WHERE `kategori`='$kategori'"));
        $get_id_daerah = mysql_fetch_array(mysql_query("SELECT `id_daerah` FROM `aset_daerah` WHERE `daerah`='$daerah'"));

        $tanggal = date("Y-m-d H:i:s");

        $sql = "INSERT INTO  `aset` (`id_aset` ,`id_daerah` ,`id_kategori` ,`nama` ,`detail` ,`longitude` ,`latitude` ,`keterangan` ,`status` ,`tanggal`)
                    VALUES (NULL ,  '$get_id_daerah[0]',  '$get_id_kategori[0]',  '$nama',  '$detail', '$longitude',  '$latitude',  '$keterangan',  'Y',  '$tanggal');";

        if(mysql_query($sql)){
            if(!file_exists($target_path)){
                if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {

                    $id_aset = mysql_fetch_array(mysql_query("SELECT `id_aset` FROM `aset` ORDER BY `id_aset` DESC LIMIT 1"));
                    mysql_query("INSERT INTO `aset_foto` (`id_foto`, `id_aset`, `foto`) VALUES (NULL, '$id_aset[0]', '$file_name');");  

                    echo "1";   // success          
                } else{         
                    echo "2"; // failed         
                }
            }else{
                echo "3";   // failed
            }
        }else{
            echo "4";   //failed
        }

        closeDB();

    }

?>

如果响应等于1,则保存过程成功

【问题讨论】:

  • 在您的 catch 块 (e.printStackTrace();) 中打印堆栈跟踪并将其发布在此处。帮助会更容易。
  • 哪里可以得到 printStackTrace() 的输出?
  • 您是否也对服务器端进行了编程?我想看看您处理发布请求和响应的代码。
  • @Otra 服务器端脚本运行良好,我的数据和图片已保存并上传到云端,它返回响应号,太混乱了,doInBackground() 上的脚本没有返回任何结果: (

标签: android android-asynctask


【解决方案1】:

在您的 IDE 或任何下降文本编辑器中打开您的 GoTo 行功能。输入 567,这就是失败的行号。不幸的是,如果没有实际的完整源代码,我们无法判断此片段中出现的第 567 行。

看起来有问题的行可能是:

String output = result.toString().trim();
error_text.setText(output);

结果可能为 null,或者 toString() 可能返回 null。 error_text 也可以为空。

【讨论】:

  • 你是对的,这是第 567 行我认为 doInBackground 的结果为空,我已经在服务器端对其进行了测试并且它可以工作,但是为什么在 android 应用程序中它不会返回任何结果?
  • 尝试记录响应。看看服务器端的输出是什么。
  • doInBackground() 中的异常块没有做它应该做的事情。问题是您返回的 e.toString() 永远不会有意义,因为您的 doPostExecute() 无法区分有效响应和异常之间的区别。异常意味着出现问题,您应该停止。让异常沸腾或将其设置为实例变量。然后在 onPostExecute() 查看实例变量并显示警报。我敢打赌你在 doBackground() 中有一个被困的 NPE,并且 NPE.getMessage() 返回 null 因此你有一个 null 传递给 onPostExecute()。
【解决方案2】:

我想我明白了。 我建议在您的doInBackground() 方法中使用return in.readline().trim();(也可以尝试不修剪)

为什么?因为在你的脚本中你是echo-ing 只有一个字符(即使使用.read() 也可以完成,所以不需要遍历InputStreamReader 对象。

onPostExecute() 方法中,我建议Log result 看看它的值是什么,然后再做任何事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多