12

ile düzen yükleme sırasında ProgressDialog göster Bu benim senaryo: Başka bir etkinliği açan bir giriş ekranım var. Faaliyet ben sadece var:SetContentView

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_details); 
} 

düzen bazı parçaların yapıldığı nedeni, tür ağır ve yüklemek için yaklaşık 1,5 saniye sürer. Şimdi, ProgressDialog görünümünü nasıl düzenleyebilirim? setContentView düzeni şişirirken bitiriyor? ile doInBackground içine koyarak, ancak UI yalnızca UI iş parçacığı üzerinden güncelleştirilemez, bu yapılamadı ile denedim. Dolayısıyla, UI dizisinde setContentView numaralı telefonu aramam gerekiyor, ancak ProgressDialog'u nerede göstermek/kapatmak zorundayım?

Yardımlarınız için minnettarım.

Fra.

DÜZENLEME:

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_empty_layout); 
    new ContentSetterTask().execute(""); 
} 

private class ContentSetterTask extends AsyncTask<String, Void, Void> { 

    public ProgressDialog prgDlg; 

    @Override 
    protected void onPreExecute() { 
     android.os.Debug.waitForDebugger(); 
     prgDlg = ProgressDialog.show(MultiPaneActivity.this, "", "Loading...", true); 

    } 

@Override 
protected Void doInBackground(String... args) { 
    android.os.Debug.waitForDebugger(); 
    ViewGroup rootView = (ViewGroup)findViewById(R.id.emptyLayout); 
    LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    View inflated = inflater.inflate(R.layout.activity_details, rootView); 
    return null; 
} 

@Override 
protected void onPostExecute(Void arg) { 
    android.os.Debug.waitForDebugger(); 
    if (prgDlg.isShowing()) 
     prgDlg.dismiss(); 
    } 
    } 
} 

View inflated = inflater.inflate(R.layout.activity_details, rootView); 

bana hata veriyor satır:

06-27 16:47:24.010: 
ERROR/AndroidRuntime(8830): Caused by:android.view.ViewRoot$CalledFromWrongThreadException: 
Only the original thread that created a view hierarchy can touch its views. 
+1

DoInBackground yönteminde el ile şişirmeyi ne dersiniz? –

+0

Yerleşim dosyanızı görmek ilginç, bence en iyisini denemek ve optimize etmek. Emulator veya telefon/tablette 1,5 saniye mi var? – Marty

+0

Merhaba, aslında eeePad Transformer'da yaklaşık 1,5 saniyedir. El ile nasıl şişirebilirim? Düzen, burada gönderilmek için oldukça uzun, ancak yaklaşık 10-12 doğrusal düzen ve bir gerçek parça (şimdilik). – frapontillo

cevap

8

Gelecek okuyucular için burada tam bir cevap vermeye karar verdim. tarihinde yapılacak İHTİYAÇ bir operasyondur bir düzen, şişirme

  1. :

    konuda harcanan birkaç saat sonra, mesele iki şey yapmaya çalışıyorum olduğunu fark etti UI iş parçacığı tasarımı tarafından. Hizmetler herhangi Dialog gösteremez çünkü bir iletişim gösteren

  2. (ProgressDialog, aslında , ancak bu sonuç değişmez), bu dediğim UI iş parçacığı yalnızca yapılabilir. iki arama UI akıştan yapıldıkça

Yani, (onCreate veya AsyncTask hiç fark, hala UI iplik s), ilk blok uygun gösteren ikinci bir. Alt satır: Bu sorun şu anda Android'de çözülemez. UI ile etkileşim için daha iyi API'ler alabileceğimizi umuyoruz, çünkü bir çeşit emdiklerimiz var.

Bu sorunu, düzeni değiştirerek ve daha açık hale getirerek (mümkünse!) Çözeceğim. Herkese teşekkürler!

+1

Bir HandlerThread kullanırsanız, görünümleri ayrı bir iş parçacığındaki el ile şişirebilirsiniz Temel olarak, görünümleri şişirdiğiniz iş parçacığı bir Looper gerektirir. – techiServices

8

ben JohnBoker önceki öneri @ izledi bu Artık hiç sahip kodudur ağır bir görüntü oluştururken aynı sorunu vardı, yaptığım şey sadece xml dosyasında linelaylaydı ve setConten olarak adlandırıldı. Bunun üzerine tView, sonra asynctask gerçek görünümü yarattım ve lineer olarak çıkışa dymanically ekledi.

Bu yöntem işe yarıyor gibi görünüyor ve işlem sırasında bir ilerleme iletişim kurabiliyordum.

+0

Evet, bu mükemmel bir seçenek gibi görünüyor! –

+0

Bunu nasıl yapabilirim? – frapontillo

+0

http://developer.android.com/resources/articles/painless-threading.html iş parçacığı için AsyncTask'da bakabilirsiniz, onPreExecute içinde gösterilen ilerleme iletişim kutusunu onPostExecute içinde reddedin. http://stackoverflow.com/questions/5292328/once-a-view-is-inflated-dynamically-as-a-list-with-a-button-attached-to-each- adresinde bir görüntüyü şişirmek için bir örnek var. satır –

0

Bu, mükemmel bir çözüm değil, şu ana kadar ihtiyacım olana en yakın olanı: İlerleme diyaloğunu (veya mesaj görünümünü veya herhangi bir şeyi) görünür kılmak ve setContentView() öğesini çağırmak arasında biraz zamana ihtiyacımız var. mesaj aslında görüntülenir.

Bunu başarmak için, kısa bir uyku() gerçekleştiren bir iş parçacığı başlatıyorum, sonra UI iş parçacığındaki setContentView() öğesini çağırıyorum. Bununla

private ProgressDialog m_Hourglass = null ; 
private Thread   m_LoadingThread = null ; 

... 

public void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 

    ... 

    m_Hourglass = new ProgressDialog(this); 
    m_Hourglass.setMessage("Loading"); 
    m_Hourglass.setIndeterminate(true); 
    m_Hourglass.setCancelable(false); 
} 

public void SetMyView(View vvv)     // Can be called from buttons. 
{ 
    if(m_LoadingThread != null) return;   // Avoid multiple press 

    m_Hourglass.show(); 

    //////////////////////////////////////////////////// 
    // Load in a thread, just to show the above message 
    // before changing layout (because setContentView() 
    // freezes the GUI.) 
    m_LoadingThread = new Thread() 
    { 
      @Override 
      public void run() 
      { 
       super.run(); 
       try     { sleep(20); } 
       catch (Exception e) { System.out.println(e); } 
       finally    { runOnUiThread(new Runnable() 
             { 
              public void run() 
              { 
               SetMyViewThreaded(); 
              } 
             }); 
            } 
       m_LoadingThread = null ; // Now we can load again 
      } 
    }; 
    m_LoadingThread.start(); 
} 

public void SetMyViewThreaded() 
{ 
    setContentView(R.layout.some_gorgeous_layout); 

    ///////////////////////////////////////////////////// 
    // Catch when to finally hide the progress dialog: 
    ImageView iv   = (ImageView) findViewById(R.id.some_view_in_the_layout); 
    ViewTreeObserver obs = iv.getViewTreeObserver();  
    obs.addOnGlobalLayoutListener(new OnGlobalLayoutListener() 
    {   
     @Override   
     public void onGlobalLayout() // The view is now loaded 
     { 
      m_Hourglass.hide(); 
     }  
    }); 

    ////////////////////////////////////////////////////// 
    // Here we can work on the layout 
    ... 
} 

Benim asıl mesele yaklaşık bir değerdir uyku (20), ve tüm makinelerde yeterli olmayabilir: Burada

bir ilerleme iletişim ile bir örnektir. Benim için çalışıyor, ancak ilerleme diyaloğunu göremiyorsanız, muhtemelen uyku süresini arttırmak zorundasınız.

İlgili konular