android输入表单的arrayindexoutofboundsexception



我有一个有38个字段的输入表单我知道这太过分了,但是我的老板希望它是这样的

有4个编辑文本和旋转器和1个imageView将上传到服务器使用http客户端

我使用AsyncTask发送这样的数据:

new asyncTask().execute(array, array, array);

因为项目太多了,我想我漏了一个我检查了很多次,但我仍然得到indexOutOfBounds异常

你能帮我找到他们或给我解决方案/建议,使更简单的代码

下面是代码(你的眼睛可能会受伤,因为这是整个代码):

http://pastebin.com/0dUss9ak

(这里写太多了)

为什么我使用字母变量的名称?如果我对每个人都使用name,我就死了。

谢谢之前

这一行

new KirimData().execute(id_user, nama, lokasi, keterangan, a, b, c, d, e, f, g, h, i, k, l, m, n, o, p, q, ad, bd, cd, dd, ed, fd, gd, hd, id, jd, kd, ld, md, nd, od, pd, qd, savedImagePath);

您似乎缺少参数j,这将(很可能)导致

中的异常

KirimData#doInBackground

为了使你的代码和变量更容易管理,我强烈建议使用HashMaps,使用字段名(即a, b, c等在你的代码)作为键:

HashMap<String, String> fieldValues = new HashMap<String, String>();
HashMap<String, Spinner> fieldSpinners = new HashMap<String, Spinner>();

通过迭代HashMap中的键并在每次迭代期间执行相同的逻辑(而不是为每个字段复制/粘贴相同的代码行),您可以大大减少代码复制(以及代码复制带来的错误)。

另外,我建议使用更有意义的字段名。它可能不会产生像现在这样紧凑的代码,但从长远来看,它更容易阅读和维护。

实际上我在onCreate中发现了一个恶意代码:

    File nfile = new File(Environment.getExternalStorageDirectory()+"/Android/data/com.nigmagrid.jm.demo/");
     nfile.mkdir();

为什么每次应用程序启动时都要创建目录?

如果你真的很想放那么多转轮,我建议您应该在以编程方式添加旋转器的方式上添加它。-首先你可以膨胀你的主布局

    LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
    ViewGroup inflatedLayout = (ViewGroup) inflater.inflate(<your layout xml>, null);

然后把Spinner的内容放到ArrayAdapter

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    adapter.add("Jembatan 1");
    adapter.add("Jembatan 2");
    adapter.add("Jembatan 3");

我不知道是否每个Spinner都有不同的内容。如果是这样,您可以声明不同的适配器或从资源创建适配器。然后添加所有你想要的旋转控件:

    for(int i=0;i<35;i++){
        Spinner s = new Spinner(this);
        s.setAdapter(adapter);
        s.setOnItemSelectedListener(new OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view,
                    int position, long id) {
                Spinner s = (Spinner) parent;
                String selectedItem = (String) s.getSelectedItem();
                Toast.makeText(InflateCoba.this, selectedItem, Toast.LENGTH_SHORT).show();
                // or you can assign it to a variable
                // selectedStr[i] = selectedItem;
            }
            @Override
            public void onNothingSelected(AdapterView<?> arg0) {
            }
        });
        inflatedLayout.addView(s);
    }

set as main View

    setContentView(inflatedLayout);

在btn_proses上单击listener,我建议你不应该创建asyncTask的新对象,在初始化时声明它,并使用你声明的实例。

    HashMap<String, Object> kirimPaket = new HashMap<String, Object>();
    kirimPaket.put("nama", nama);
    kirimPaket.put("keterangan", keterangan); // and do the rest ..
    kirimPaket.put("spinnerItem", selectedStr);
    kirim.execute(kirimPaket);

,其中kirm是KirimData的实例。使用HashMap并将数据包放在那里,这会使它变得简单。

    protected class KirimData extends AsyncTask<HashMap<String, Object>, Void, String>

实际上我不喜欢asyncTask发送参数的方式,谷歌应该做得简单。然后完成它

    @Override
        protected String doInBackground(HashMap<String, Object>... params) {
            try{
                HttpClient httpClient = CustomHttpClient.getHttpClient();
                HttpPost postRequest = new HttpPost(VarsUrl.getServerAddress()+"simpan-inspeksi-jembatan.php");
                MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
                String nama = params[0].get("nama");
                String keterangan = params[0].get("keterangan"); // and do the rest  ..
                String[] selectedStr = params[0].get("spinnerItem");
                reqEntity.addPart("nama", new StringBody(nama));
                reqEntity.addPart("keterangan", new StringBody(keterangan)); // and do the rest  ..
                for(int i=0;i<selectedStr.length;i++){
                    reqEntity.addPart("item_"+i, new StringBody(selectedStr[i]));
                }
           ....

最新更新