Как добавить в основной макет ImageView, управляемый из другого потока?

#android #multithreading #android-layout #imageview

#Android #многопоточность #android-layout #imageview

Вопрос:

Я создаю приложение для Android. Я достиг своей цели с помощью одного основного потока, нажав кнопку!!! (показать изображение, сохраненное на SD-карте в ImageView) Но мне нужно сделать это с помощью потоков, чтобы сэкономить время и потому, что я буду создавать другие потоки.

Проблема, когда я делаю это в новом потоке, появляется предупреждение, которое сообщает мне:

«Только исходный поток, создавший иерархию представлений, может касаться своих представлений».

И изображение не открывается.

Вот этот код:

 public class intsocketclient extends Activity implements  OnClickListener{
    public ImageView imagen;
        private Button connectPhones;              
        private Handler conectarhandler = null;
    private Runnable conectarunner = null;
public boolean condicion = true;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);    
            imagen = (ImageView) findViewById(R.id.imagen);
            connectPhones = (Button) findViewById(R.id.connect_phones);
            connectPhones.setOnClickListener(this);

            conectarhandler = new Handler();        
            conectarunner = new Runnable() { 
                public void run() {
                conectayenvia(); 
            conectarhandler.post(this);          

                }
          };                  
        }

@Override
public void onClick(View v) {
    // TODO Auto-generated method stub.
     if(v==connectPhones) {              
         new Thread (conectarunner).start();                 
     }
}

public void conectayenvia () {
    if (condicion){              
                  condicion = false;
                  Bitmap bMap = BitmapFactory.decodeFile("/sdcard/recibido.jpg");
                  imagen.setImageBitmap(bMap);                                      
     }  
    }   
}
 

Но мне действительно нужно, чтобы это было так.

Можно ли взять основной макет (оригинал «main.xml «) и каким-то образом «добавить» поверх него другой основной файл (a «threadmain.xml » который содержит только ImageView), но также с возможностью нажатия кнопок и других вещей первого оригинала «main.xml » планировка????????

Ответ №1:

используйте AsyncTask, поскольку он будет обрабатывать потоки автоматически, методы preExecute и postExecute AsyncTask выполняются в потоке пользовательского интерфейса.

   private class DF extends AsyncTask<Void, Void, Void>{
         private Bitmap bMap;
    @Override
    protected Void doInBackground(Void... params) {
                    if (condicion){              
              condicion = false;
              bMap = BitmapFactory.decodeFile("/sdcard/recibido.jpg");

                     }
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
              imagen.setImageBitmap(bMap);                                      
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }
}
 

вызовите AsyncTask в onClick.

 @Override
public void onClick(View v) {
    // TODO Auto-generated method stub.
     if(v==connectPhones) {              
             new DF().execute();
     }
}
 

Ответ №2:

Ваша проблема в том, что вы пытаетесь запускать методы пользовательского интерфейса не в потоке пользовательского интерфейса. Решение состоит в том, чтобы вызвать runOnUiThread из другого потока.