как обновить пользовательский интерфейс из фоновой задачи

Мое приложение не работает на Android версии 4.1, выдает исключение, например android.os.NetworkOnMainThreadException

у меня есть поиск в stackoverflow, который советует мне сделать сетевой поток в фоновом режиме AsyncTask, поэтому перед использованием backgroundtask мой экран выглядит следующим образом: http://imgur.com/PlhS03i показать несколько строк в тегах питания и ингредиентов после использования backgroundtask мой экран выглядит так http://imgur.com/zUvxNpy показывать только одну строку в тегах ингредиентов и питательных веществ

перед кодом фоновой задачи см. ниже

public class fifthscreen extends Activity {
String num = null;
TextView ingredient;

long Menu_ID;
String dish_name;

String status;

HorizontalListView listview;
CategoryListAdapter3 cla;
String DescriptionAPI;

TextView txt1, txt2, txt3;
ImageView img1;
String URL, URL2;
String SelectMenuAPI;

static ArrayList<Long> Category_ID = new ArrayList<Long>();
static ArrayList<String> Category_name = new ArrayList<String>();
static ArrayList<String> Category_image = new ArrayList<String>();

public static String allergen2;
private AQuery androidAQuery;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.fifthscreen);
    ingredient = (TextView) findViewById(R.id.ingredient);
    img1 = (ImageView) findViewById(R.id.test_button_image);

    txt1 = (TextView) findViewById(R.id.menuname);
    txt3 = (TextView) findViewById(R.id.description);

    Intent iGet = getIntent();

    ImageView options = (ImageView) findViewById(R.id.options5);
    androidAQuery = new AQuery(this);

    options.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent iMenuList = new Intent(fifthscreen.this,
                    LinkButtons.class);
            startActivity(iMenuList);
        }
    });

    dish_name = iGet.getStringExtra("dish_name");

    listview = (HorizontalListView) this.findViewById(R.id.listview2);

    cla = new CategoryListAdapter3(fifthscreen.this);
    listview.setAdapter(cla);

    parseJSONData();

}

void clearData() {
    Category_ID.clear();
    Category_name.clear();
    Category_image.clear();

}

public void parseJSONData() {

    SelectMenuAPI = Utils.dishdescription + dish_name;

    clearData();
    URL = SelectMenuAPI;
    URL2 = URL.replace(" ", "%20");

    try {

        HttpClient client = new DefaultHttpClient();
        HttpConnectionParams
                .setConnectionTimeout(client.getParams(), 15000);
        HttpConnectionParams.setSoTimeout(client.getParams(), 15000);
        HttpUriRequest request = new HttpGet(URL2);
        HttpResponse response = client.execute(request);
        InputStream atomInputStream = response.getEntity().getContent();
        BufferedReader in = new BufferedReader(new InputStreamReader(
                atomInputStream));

        String line;
        String str = "";
        while ((line = in.readLine()) != null) {
            str += line;
        }

        JSONObject json2 = new JSONObject(str);

        status = json2.getString("status");
        if (status.equals("1")) {

            JSONArray school2 = json2.getJSONArray("data");

            for (int i = 0; i < school2.length(); i++) {

                String name = school2.getJSONObject(0).getString("name");
                txt1.setText(name);

                String description = school2.getJSONObject(0).getString(
                        "description");

                txt3.setText(description);

                String url1 = school2.getJSONObject(0).getString("image");

                androidAQuery.id(img1).image(url1, false, false);

            }

            JSONObject school3 = json2.getJSONObject("dish_nutrition");

            final TableLayout table = (TableLayout) findViewById(R.id.table2);

            for (int j = 0; j < school3.length(); j++) {

                String s = String.valueOf(j + 1);

                final View row = createRow(school3.getJSONObject(s));
                table.addView(row);

            }

            JSONArray school4 = json2.getJSONArray("dish_allergen");
            //
            for (int i = 0; i < school4.length(); i++) {
                JSONObject object = school4.getJSONObject(i);

                Category_ID.add((long) i);
                Category_name.add(object.getString("name"));
                Category_image.add(object.getString("image"));
                listview.setAdapter(cla);

            }

    final LinearLayout table3 = (LinearLayout) findViewById(R.id.table3);

            JSONArray school5 = json2.getJSONArray("dish_ingredient");

            for (int i = 0; i < school5.length(); i++) {

                final View row2 = createRow2(school5.getJSONObject(i));
                table3.addView(row2);

            }

        }

        else {

            JSONArray school2 = json2.getJSONArray("data");
            for (int i = 0; i < school2.length(); i++) {
                JSONObject object = school2.getJSONObject(i);

                Category_ID.add((long) i);
                Category_name.add(object.getString("name"));

            }

        }

    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        // IOConnect = 1;
        e.printStackTrace();
    } catch (JSONException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

public View createRow(JSONObject item) throws JSONException {
    View row = getLayoutInflater().inflate(R.layout.rows, null);
    ((TextView) row.findViewById(R.id.localTime)).setText(item
            .getString("qty"));
    ((TextView) row.findViewById(R.id.apprentTemp)).setText(item
            .getString("name"));

    return row;
}

public View createRow2(JSONObject item) throws JSONException {

    View row2 = getLayoutInflater().inflate(R.layout.row2, null);
    ((TextView) row2.findViewById(R.id.name)).setText(item
            .getString("name"));
    ((TextView) row2.findViewById(R.id.subingredients)).setText(item
            .getString("sub_ingredients"));

    return row2;
}

    }

После использования AsyncTask см. этот код ниже

 public class fifthscreen extends Activity {
String num = null;
TextView ingredient;

long Menu_ID;
String dish_name;

String status;

HorizontalListView listview;
CategoryListAdapter3 cla;
String DescriptionAPI;

TextView txt1, txt2, txt3;
ImageView img1;
String URL, URL2;
String SelectMenuAPI;
String description;

int IOConnect = 0;
String name;
String url1;
TableLayout table;
LinearLayout table3;
View row;
View row2;

static ArrayList<Long> Category_ID = new ArrayList<Long>();
static ArrayList<String> Category_name = new ArrayList<String>();
static ArrayList<String> Category_image = new ArrayList<String>();
public static String allergen2;
private AQuery androidAQuery;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.fifthscreen);
    if (android.os.Build.VERSION.SDK_INT > 9) {
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
                .permitAll().build();
        StrictMode.setThreadPolicy(policy);
    }
    ingredient = (TextView) findViewById(R.id.ingredient);
    img1 = (ImageView) findViewById(R.id.test_button_image);

    txt1 = (TextView) findViewById(R.id.menuname);
    // txt2 = (TextView) findViewById(R.id.test_button_text1);
    txt3 = (TextView) findViewById(R.id.description);

    table = (TableLayout) findViewById(R.id.table2);
    table3 = (LinearLayout) findViewById(R.id.table3);

    Intent iGet = getIntent();

    ImageView options = (ImageView) findViewById(R.id.options5);
    androidAQuery = new AQuery(this);

    options.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent iMenuList = new Intent(fifthscreen.this,
                    LinkButtons.class);
            startActivity(iMenuList);
        }
    });

    dish_name = iGet.getStringExtra("dish_name");

    listview = (HorizontalListView) this.findViewById(R.id.listview2);

    cla = new CategoryListAdapter3(fifthscreen.this);

    new getDataTask().execute();

    // listview.setAdapter(cla);

    ImageView btnback = (ImageView) findViewById(R.id.btnback);

    btnback.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            finish();
        }
    });

    parseJSONData();

}

void clearData() {
    Category_ID.clear();
    Category_name.clear();
    Category_image.clear();

}

public class getDataTask extends AsyncTask<Void, Void, Void> {

    getDataTask() {

    }

    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub

    }

    @Override
    protected Void doInBackground(Void... arg0) {
        // TODO Auto-generated method stub
        parseJSONData();
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        // TODO Auto-generated method stub
        txt1.setText(name);
         txt3.setText(description);
        androidAQuery.id(img1).image(url1, false, false);

        table.addView(row);
        table3.addView(row2);
        listview.setAdapter(cla);

    }
}

public void parseJSONData() {

    SelectMenuAPI = Utils.dishdescription + dish_name;

    clearData();
    URL = SelectMenuAPI;
    URL2 = URL.replace(" ", "%20");

    try {

        HttpClient client = new DefaultHttpClient();
        HttpConnectionParams
                .setConnectionTimeout(client.getParams(), 15000);
        HttpConnectionParams.setSoTimeout(client.getParams(), 15000);
        HttpUriRequest request = new HttpGet(URL2);
        HttpResponse response = client.execute(request);
        InputStream atomInputStream = response.getEntity().getContent();
        BufferedReader in = new BufferedReader(new InputStreamReader(
                atomInputStream));

        String line;
        String str = "";
        while ((line = in.readLine()) != null) {
            str += line;
        }

        JSONObject json2 = new JSONObject(str);

        status = json2.getString("status");
        if (status.equals("1")) {

            JSONArray school2 = json2.getJSONArray("data");

            for (int i = 0; i < school2.length(); i++) {

                name = school2.getJSONObject(0).getString("name");

                description = school2.getJSONObject(0).getString(
                        "description");

                url1 = school2.getJSONObject(0).getString("image");

            }

            JSONObject school3 = json2.getJSONObject("dish_nutrition");

            for (int j = 0; j < school3.length(); j++) {

                String s = String.valueOf(j + 1);

                row = createRow(school3.getJSONObject(s));

            }

            JSONArray school4 = json2.getJSONArray("dish_allergen");
            //
            for (int i = 0; i < school4.length(); i++) {
                JSONObject object = school4.getJSONObject(i);

                Category_ID.add((long) i);
                Category_name.add(object.getString("name"));
                Category_image.add(object.getString("image"));

            }

            JSONArray school5 = json2.getJSONArray("dish_ingredient");

            for (int i = 0; i < school5.length(); i++) {

                row2 = createRow2(school5.getJSONObject(i));

            }

        }

        else {

            JSONArray school2 = json2.getJSONArray("data");
            for (int i = 0; i < school2.length(); i++) {
                JSONObject object = school2.getJSONObject(i);

                Category_ID.add((long) i);
                Category_name.add(object.getString("name"));

            }

        }

    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        // IOConnect = 1;
        e.printStackTrace();
    } catch (JSONException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

public View createRow(JSONObject item) throws JSONException {
    View row = getLayoutInflater().inflate(R.layout.rows, null);
    ((TextView) row.findViewById(R.id.localTime)).setText(item
            .getString("qty"));
    ((TextView) row.findViewById(R.id.apprentTemp)).setText(item
            .getString("name"));

    return row;
}

public View createRow2(JSONObject item) throws JSONException {

    View row2 = getLayoutInflater().inflate(R.layout.row2, null);
    ((TextView) row2.findViewById(R.id.name)).setText(item
            .getString("name"));
    ((TextView) row2.findViewById(R.id.subingredients)).setText(item
            .getString("sub_ingredients"));

    return row2;
}

 }

Пожалуйста помоги

Заранее спасибо...:)


person smart guy    schedule 02.10.2013    source источник
comment
я думаю, что эти строки не обновляются в postExecute row2 = createRow2 (school5.getJSONObject (i));   -  person smart guy    schedule 02.10.2013
comment
почему вы звоните parsejsondata дважды? в асинтаске, а также в oncreate   -  person Siddhesh    schedule 02.10.2013
comment
в oncreate я забыл удалить, просто скажите мне, как показать значения этого цикла row = createRow (school3.getJSONObject (s)); после выполнения   -  person smart guy    schedule 02.10.2013
comment
Вы действительно умный парень? :) проверьте: android.os.NetworkOnMainThreadException   -  person Paresh Mayani    schedule 02.10.2013
comment
Пареш, просто скажи мне, что я обновляю свой пользовательский интерфейс в forloop перед использованием asyntask в этой строке final View row = createRow(school3.getJSONObject(s)); как обновить пользовательский интерфейс таким же образом из postexecute   -  person smart guy    schedule 02.10.2013
comment
Вы должны использовать залп для JSON! И, возможно, UniversalImageLoader для изображения   -  person An-droid    schedule 02.10.2013


Ответы (4)


Вы можете использовать **runOnUiThread()** следующим образом:

try {
   // code runs in a thread
   runOnUiThread(new Runnable() {
       @Override
       public void run() {

         // YOUR CODE

       }
  });
} catch (final Exception ex) {
     Log.i("---","Exception in thread");
}
person Pratik Butani    schedule 02.10.2013
comment
как обновить пользовательский интерфейс, используя forloop внутри postexecute - person smart guy; 02.10.2013

Используйте объект Handler из вашей MainActivity и опубликуйте runnable. Чтобы использовать его из фона, вам нужно сделать объект статическим, который вы можете вызывать вне своей MainActivity, или вы можете создать статический экземпляр Activity для доступа к нему.

Внутри деятельности

    private static Handler handler;


    handler = new Handler();

    handler().post(new Runnable() {

        public void run() {
            //ui stuff here :)
        }
    });

    public static Handler getHandler() {
       return handler;
    }

Вне деятельности

    MainActivity.getHandler().post(new Runnable() {

            public void run() {
                //ui stuff here :)
            }
        });
person JWqvist    schedule 02.10.2013
comment
Создайте обработчик как статический в MainActivity, затем создайте статический геттер, чтобы вы могли вызывать метод из фона. - person JWqvist; 02.10.2013
comment
Используйте этот метод, когда вы манипулируете элементами пользовательского интерфейса, такими как набор текста. - person JWqvist; 02.10.2013

Вам нужно создать класс AsyncTask и использовать его Подробнее здесь: AsyncTask

Пример будет выглядеть так:

private class UploadTask extends AsyncTask<Void, Void, Void>
{
    private String in;

    public UploadTask(String input)
    {
        this.in = input;
    }

    @Override
    protected void onPreExecute()
    {
        //start showing progress here
    }

    @Override
    protected Void doInBackground(Void... params)
    {
      //do your work
        return null;
    }

    @Override
    protected void onPostExecute(Void result)
    {
        //stop showing progress here
    }

}

И запустить задачу следующим образом:

UploadTask ut = новая UploadTask (ввод); ут.выполнить();

person andDev    schedule 02.10.2013
comment
но посмотрите мой код, в котором я использую forloop внутри метода parsemethod, и добавьте row2 = createRow2 (school5.getJSONObject (i)); эта строка не работает с методом postexecute и просто показывает только одну строку - person smart guy; 02.10.2013
comment
мне это уже нравилось add row2 = createRow2(school5.getJSONObject(i)); и внутри postexecute шоу, подобное этому table3.addView(row2); - person smart guy; 02.10.2013
comment
как показать это значение цикла row = createRow(school3.getJSONObject(s)); из parseJSONData(); показать в postexecute - person smart guy; 02.10.2013

вы обрабатываете пользовательский интерфейс в этих методах

public View createRow(JSONObject item) throws JSONException {
    View row = getLayoutInflater().inflate(R.layout.rows, null);
    ((TextView) row.findViewById(R.id.localTime)).setText(item
            .getString("qty"));
    ((TextView) row.findViewById(R.id.apprentTemp)).setText(item
            .getString("name"));

    return row;
}

public View createRow2(JSONObject item) throws JSONException {

    View row2 = getLayoutInflater().inflate(R.layout.row2, null);
    ((TextView) row2.findViewById(R.id.name)).setText(item
            .getString("name"));
    ((TextView) row2.findViewById(R.id.subingredients)).setText(item
            .getString("sub_ingredients"));

    return row2;
}

которые вызываются в фоновом потоке

если возможно, сделайте это в onPostExecute или используйте runOnUiThread и обработчик.

person Siddhesh    schedule 02.10.2013