在Activity的“onCreate”方法中从在线MySQL DB获取数据

时间:2017-11-14 21:41:27

标签: php android mysql android-asynctask adapter

我正在开发需要从在线MySQL数据库获取数据并在活动布局中将其显示为列表的应用程序。

问题是我的应用程序收到错误“尝试在空对象引用上调用接口方法'int java.util.List.size()'”

在onCreate方法中,我调用asyncTask类来从服务器获取数据,而不是在该行代码下面,我通过适配器将数据设置为listview,这是我的布局。 启动该活动时,我收到错误。

我应该在启动Activity之前从服务器获取数据吗?或问题是别的什么? 当我在浏览器中检查时,我的php文件正常工作。

这是onCreate方法:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.invoice_list);
    final ListView listView1 = (ListView) findViewById(R.id.invoicelist);
    InvoiceDownloader task = new InvoiceDownloader();

    task.execute(new String[] { "http://10.0.2.2/company/getinvoices.php" });
    ArrayAdapter<Invoice> adapter = new ArrayAdapter<Invoice>(this, android.R.layout.simple_list_item_1, invoices);
    listView1.setAdapter(adapter);
}

编辑:

我按照大家的建议修复了它,现在没有错误,活动打开,但它仍然没有显示来自在线数据库的任何数据。 这里是编辑onCreate()方法:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.invoice_list);
    adapter = new ArrayAdapter<Invoice>(this, android.R.layout.simple_list_item_1);
    listView1 = (ListView) findViewById(R.id.invoicelist);
    InvoiceDownloader task = new InvoiceDownloader();
    task.execute(new String[] { "http://10.0.2.2/company/getinvoices.php" });
    adapter.notifyDataSetChanged();
}

这里是AsyncTask类:

public class InvoiceDownloader extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {
        String response = "";
        try {
            response += getHttpContent(params[0]);
        } catch (IOException e) {
            Log.e("error", e.toString());
        }
        return response;
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        adapter.addAll(invoices);
        listView1.setAdapter(adapter);

        Toast.makeText(getApplicationContext(), s, Toast.LENGTH_SHORT).show();
    }

    public String getHttpContent(String urlStr) throws IOException {

        String response = "";

        try {
            URL url = new URL(urlStr);
            HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();

            StringBuilder sb = new StringBuilder();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
            String json;
            while ((json = bufferedReader.readLine()) != null) {
                sb.append(json + "\n");
            }

            JSONArray jsonArray = new JSONArray(sb.toString().trim());

            for (int i = 0; i < jsonArray.length(); i++) {
                Invoice invoice = new Invoice();
                JSONObject inv = jsonArray.getJSONObject(i);

                String companyNameOne = inv.getString("companyNameOne");
                String companyNameTwo = inv.getString("companyNameTwo");
                String address = inv.getString("address");
                String postalCode = inv.getString("postalCode");
                String city = inv.getString("city");
                String oib = inv.getString("oib");
                String email = inv.getString("email");
                int comple = inv.getInt("completed");
                String completed = String.valueOf(comple);
                String workOrderNumber = inv.getString("workOrderNumber");
                String price = inv.getString("price");

                System.out.println("Company Name 1: " + companyNameOne + " Company Name 2: " + companyNameTwo + " address: " + address + " postalCode: " + postalCode + " city: " + city + " oib: " + oib + " email: " + email + " completed: " + completed + " work order num: " + workOrderNumber + " price: " + price);

                invoice.setCompanyNameOne(companyNameOne);
                invoice.setCompanyNameTwo(companyNameTwo);
                invoice.setAddress(address);
                invoice.setPostalCode(postalCode);
                invoice.setCity(city);
                invoice.setOib(oib);
                invoice.setEmail(email);
                invoice.setCompleted(completed);
                invoice.setWorkOrderNumber(workOrderNumber);
                invoice.setPrice(price);

                invoices.add(invoice);
            }
            return response;
        } catch (Exception e) {
            return null;
        }
    }
}

第二次编辑:

我明白了。对不起,这个问题在修复错误后没有显示数据是我的错误。在这部分:

JSONObject inv = jsonArray.getJSONObject(i);

                String companyNameOne = inv.getString("companyNameOne");
                String companyNameTwo = inv.getString("companyNameTwo");
                String address = inv.getString("address");
                String postalCode = inv.getString("postalCode");
                String city = inv.getString("city");
                String oib = inv.getString("oib");
                String email = inv.getString("email");
                int comple = inv.getInt("completed");
                String completed = String.valueOf(comple);
                String workOrderNumber = inv.getString("workOrderNumber");
                String price = inv.getString("price");

(“”)中的那些字符串ALL必须是小写字母,因为我在PHP中以这种方式编写它们。

谢谢大家的帮助。

3 个答案:

答案 0 :(得分:1)

可能你没有得到服务器的回复,这就是为什么列表为空,编辑发布堆栈跟踪并能够帮助你更好的原因,看看这个post它看起来像你有同样的问题,原因是在调用Web服务(SQL db) 我的猜测是你的stacktrace的第二行是ArrayAdapter.getCount() 因为这里通常是问题,ArrayAdapter调用的方法返回一个List,在你的情况下是null,因为不从服务器检索。也许是一个JsonException,所以你应该用try catch添加一个异常来管理服务器没有检索到响应时会发生什么。

 public int   getCount() {


    return mObjects.size();

}

异步任务比3年前少用,现在几乎所有社区都使用Retrofit来进行异步调用以及RXJava

答案 1 :(得分:1)

您应该通过适配器将数据设置为asyncTask的onPostExecute()上的listview。 (https://developer.android.com/reference/android/os/AsyncTask.html

由于任务是异步的,因此在服务器的响应到达之前,您正尝试访问发票列表的数据。

答案 2 :(得分:1)

您正在将非初始化集合(null)传递给适配器。这就是为什么当适配器试图获取集合的大小时你得到NullPointerException。 你需要这样做:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.invoice_list);
    ...
    invoices = new ArrayList<>();
    ArrayAdapter<Invoice> adapter = new ArrayAdapter<Invoice>(this, android.R.layout.simple_list_item_1, invoices);
    listView1.setAdapter(adapter);
}

然后使用onPostExecute AsyncTask中的新项目填充集合并致电adapter.notifyDataSetChanged