Установка текста в EditText вызывает сбой приложения - PullRequest
0 голосов
/ 03 ноября 2018

Я программирую приложение в Android Studio. Я беру файл json с сервера, затем извлекаю его в строки и хочу показать в EditText, чтобы он был изменяемым.

Вот мой код

 protected String doInBackground(String... atr) {
        new Thread(new Runnable() {
            public void run() {
                int success;
                try {
                    List<NameValuePair> params = new ArrayList<NameValuePair>();
                    params.add(new BasicNameValuePair("pid", pid));
                    params.add(new BasicNameValuePair("name", table_name));


                    JSONObject json = jsonParser.makeHttpRequest(url_product_details, "GET", params);
                    Log.d("Single Product Details", json.toString());

                    success = json.getInt(TAG_SUCCESS);
                    if (success == 1) {
                        JSONArray productObj = json.getJSONArray(TAG_PRODUCT);
                        JSONObject product = productObj.getJSONObject(0);

                        String _name = product.getString("name");
                        name.setText(_name, EditText.BufferType.EDITABLE);

                        if(!product.isNull("price")) {
                            Integer _price = product.getInt("price");
                            price.setText(_price, EditText.BufferType.EDITABLE);
                        }
                        if(!product.isNull("quantity")) {
                            Integer _quantity = product.getInt("quantity");
                            quantity.setText(_quantity, EditText.BufferType.EDITABLE);
                        }
                        if(!product.isNull("promotion")) {
                            Integer _promotion = product.getInt("promotion");
                            promotion.setText(_promotion, EditText.BufferType.EDITABLE);
                        }
                    } else {
                        Intent i = new Intent(getApplicationContext(), AllProductsActivity.class);
                        i.putExtra(TAG_PID, pid);
                        i.putExtra("list_name", table_name);
                        startActivity(i);
                        finish();
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        return null;
    }

к сожалению, когда я пытаюсь, как это приложение падает, когда я пытаюсь загрузить текст в EditText. Я подтвердил, что EditText не является нулевым, Strings тоже. Нет сообщения об ошибке, что мешает этой проблеме. У кого-нибудь есть идеи? Я искал везде (возможно, я не могу искать xD) и не нашел ничего разумного.

Ответы [ 2 ]

0 голосов
/ 03 ноября 2018

Когда вы взаимодействуете с любым элементом пользовательского интерфейса, например EditText, вы не можете использовать ничего, кроме потока пользовательского интерфейса (или основного потока).

Другими словами, элементы пользовательского интерфейса должны быть изменены из потока пользовательского интерфейса.

Что вы можете сделать:

  1. Перемещение кодов, в которых элемент пользовательского интерфейса (например, EditText) обновляется из doInBackground (String ... str) в onPostExecuted (String str).

  2. Каждый раз, когда вы используете какой-либо элемент пользовательского интерфейса из другого потока, используйте метод View.post (Runnable runnable). Нравится:

    editText.post(
            new Runnable() {
                @Override
                public void run() {
                    //do your work
                }
            }
    );
    

    или используйте метод Activity.runOnUiThread (Runnable runnable), когда он находится внутри Activity

     runOnUiThread(
            new Runnable() {
                @Override
                public void run() {
                    //do your work
                }
            }
    );
    
0 голосов
/ 03 ноября 2018

Во-первых, разверните код из этой темы. doInBackground() уже асинхронный, поэтому он избыточен. Либо используйте Thread или AsyncTask, но не оба.

Во-вторых, представления, такие как EditText, могут быть изменены только в основном или потоке пользовательского интерфейса. Когда вы запускаете setText() или любые другие методы в View, он должен находиться в главном потоке.

Если это внутри Activity, вы можете использовать:

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        //appropriate setText()
    }
});

В противном случае вам нужно будет использовать обработчик. Создайте глобальную переменную:

private Handler handler = new Handler(Looper.getMainLooper());

и вместо runOnUiThread() используйте handler.post() с тем же синтаксисом (просто замените runOnUiThread на handler.post).

Однако есть и третье. Вы не должны обрабатывать JSON String в фоновом режиме. Вы должны только получить строку в этой точке. Ваша логика должна идти в onPostExecute(), который уже выполняется в основном потоке для вас.

Ваш код должен выглядеть следующим образом:

@Override
protected String doInBackground(String... atr) {
    try {
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("pid", pid));
        params.add(new BasicNameValuePair("name", table_name));

        JSONObject json = jsonParser.makeHttpRequest(url_product_details, "GET", params);
        Log.d("Single Product Details", json.toString());

        int success = json.getInt(TAG_SUCCESS);
        if (success == 1) {
            return json; //return the JSON String on success
        } else {
            Intent i = new Intent(getApplicationContext(), AllProductsActivity.class);
            i.putExtra(TAG_PID, pid);
            i.putExtra("list_name", table_name);
            startActivity(i);
            finish();
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }

    return null; //return null for any other result
}

@Override
protected void onPostExecute(String result) {
    if (result != null) { //make sure result isn't null
        JSONArray productObj = result.getJSONArray(TAG_PRODUCT);
        JSONObject product = productObj.getJSONObject(0);

        String _name = product.getString("name");
        name.setText(_name, EditText.BufferType.EDITABLE);

        if (!product.isNull("price")) {
            Integer _price = product.getInt("price");
            price.setText(_price, EditText.BufferType.EDITABLE);
        }
        if (!product.isNull("quantity")) {
            Integer _quantity = product.getInt("quantity");
            quantity.setText(_quantity, EditText.BufferType.EDITABLE);
        }
        if (!product.isNull("promotion")) {
            Integer _promotion = product.getInt("promotion");
            promotion.setText(_promotion, EditText.BufferType.EDITABLE);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...