我有一个有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]));
}
....