Ошибка при попытке добавить представление в RelativeLayout

#android #android-relativelayout

#Android #android-relativelayout

Вопрос:

Я пытаюсь использовать AsyncTask для получения некоторой информации из удаленной базы данных и использовать ее для создания динамического списка на экране. Сначала я выполняю AsyncTask, и когда он завершается, я вызываю метод моей активности, чтобы изменить экран, но он выдает ошибку, которую я не могу исправить.

Это код моей деятельности:

 public class MainActivity extends Activity {
Button but;
ArrayList<String> array;
ArrayList<String> array2;
JSONArray players = null;
RelativeLayout rl;


@Override
protected void onStart(){
    super.onStart();

    Intent intent = getIntent();

    final String  s= intent.getStringExtra("firstKeyName");



    RelativeLayout.LayoutParams params;
    rl = (RelativeLayout) findViewById(R.id.marco);




         Hilo hilo = new Hilo(this, s);
         hilo.execute();




      }

protected void pantalla(final JSONArray players){


     RelativeLayout.LayoutParams params;
      DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);

      final Integer h= metrics.heightPixels;
      final Integer w= metrics.widthPixels;


      Button b1 = new Button(this);
      params = new RelativeLayout.LayoutParams((int) (w*0.8), (int) (h*0.16));
      params.leftMargin = (int) (0);
      params.topMargin = (int) (h*0.5);

     rl.addView(b1,params);

}
}
  

Я думаю, что код моего метода onCreate не является необходимым.
И это код AsyncTask

 public class Hilo extends AsyncTask<Object,Void,Void> {

private MainActivity activity2;
 JSONArray players = null;
 String s;

    public Hilo(MainActivity activity, String s2)
    {
        activity2 = activity;
        s=s2;
    }

@Override
protected Void doInBackground(Object... arg0) {
    // TODO Auto-generated method stub
    //players = new JSONArray();

      if(hay_internet()){

          RestClient client = null;



         client = new RestClient("myurl");


           try {
               client.Execute(RestClient.RequestMethod.GET);
           } catch (Exception e) {

           }

           String response = client.getResponse();

           try {

             JSONObject jObject=new JSONObject(response);
           players = new JSONArray(jObject.getString("questions"));




              } catch (Exception e) {

                }


      }
           activity2.pantalla(players);
        return null;


}

public boolean hay_internet(){

    RestClient client = new RestClient("myurl");

    Integer i=0;
       try {
           client.Execute(RestClient.RequestMethod.GET);
       } catch (Exception e) {

       }

       String response = client.getResponse();

       try {

         JSONObject jObject=new JSONObject(response);
         JSONArray players = new JSONArray(jObject.getString("questions"));

          i=players.getJSONObject(0).getString("Jugador").toString().length();


          } catch (Exception e) {

            }

       return (i==7);
    }







}
  

Метод hayy_internet() предназначен только для проверки наличия подключения к Интернету.

Ошибка появляется, когда я пытаюсь добавить представление в метод pantalla(), используя RelativeLayout, который является глобальной переменной, которую я инициализировал в методе OnStart() .

Комментарии:

1. Правильное форматирование вашего кода НЕ повредит. Пожалуйста, сделайте так, как сможете.

Ответ №1:

Вы пропустили вызов setContentView метода перед ссылкой RelativeLayout . Переопределите onCreate метод и вызовите его:

 @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.<YourXmlContainingRelativelayout>);
}
  

[Обновить]
Виновником является этот вызов:

 activity2.pantalla(players);
  

Переопределите onPostExecute метод AsyncTask и вызовите его оттуда. Причина в том, что Android не позволяет вам создавать материалы, связанные с пользовательским интерфейсом, в фоновом потоке. Вы должны выполнять связанные с пользовательским интерфейсом материалы в основном потоке.

 @Override
protected void onPostExecute(Object arg0) {
    //do something after background execution is complete
    //Executes on main thread
}
  

Ответ №2:

Вы не можете обновить / добавить представление в методе AsynkTask (т. Е. В любом фоновом потоке / методе) Вы должны сделать это в потоке пользовательского интерфейса. onPostExecute() AsynkTask выполняется в потоке пользовательского интерфейса, поэтому вызовите метод r в onPostExecute().

Также используйте

  @Override
 public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(layoutfilename);
 }
  

Комментарии:

1. Я выполнил setContentView в моем onCreate(), проблема в том, что я хочу установить представление в методе pantalla(). Как я могу это сделать?

2. Это то, что я сказал, вызовите pantalla(players); этот метод в onPostExecute() methos из AsyncTask . Не вызывайте его в doInBackground.

3. Я сделал это, и ошибка не исправлена. Я думаю, проблема в том, что я пытаюсь добавить представление из метода, который не является onCreate() , OnStart() и т.д.