Android ProgressDialog Progress Bar Dinge zu tun, in der richtigen Reihenfolge

? FauxReal @ | Original: StackOverFlow
---

Ich gerade habe, aber ich habe ein kleines Problem in der Ordnung der Dinge geht aus . Genauer gesagt, in meinem Thread () Ich gründe ein Array, das von einem Spinner verwendet wird. Problem ist der Spinner wird ganz eingestellt, und im Grunde vor meiner Festplatte geschieht () beendet ist, so ist es stellt sich mit einem null -Array.

Wie verbinde ich die Spinner Arrayadapter mit einer Reihe, die von einem anderen Thread geladen wird ?

Ich habe den Code unten, um das, was ich denke, ist notwendig, um das Problem zu verstehen geschnitten, aber lassen Sie mich wissen, wenn mehr benötigt wird. Das Problem tritt auf, ob oder nicht Refresh () aufgerufen wird.

In die gleiche Richtung, manchmal möchte ich loaddata aus dem Menü () aufrufen. Direkt im Anschluss an loaddata (), wenn ich einen Toast auf der nächsten Zeile das verursacht eine forceclose, das auch, weil, wie ich bin Umsetzung ProgressDialog ist Feuer versuchen .

DANKE FÜR DAS SCHAUEN

public class CMSHome extends Activity { 

private static List<String> pmList = new ArrayList<String>();

// Instantiate helpers
PMListHelper plh = new PMListHelper();
ProjectObjectHelper poc = new ProjectObjectHelper();

// These objects hold lists and methods for dealing with them
private Employees employees;
private Projects projects;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    // Loads data from filesystem, or webservice if necessary
    loadData();

    // Capture spinner and associate pmList with it through ArrayAdapter
    spinner = (Spinner) findViewById(R.id.spinner);
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(
                    this, android.R.layout.simple_spinner_item,
                    pmList);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner.setAdapter(adapter);

    //---the button is wired to an event handler---
    Button btn1 = (Button)findViewById(R.id.btnGetProjects);
    btn1.setOnClickListener(btnListAllProjectsListener);
    spinner.setOnItemSelectedListener(new MyOnItemSelectedListener());
}


private void loadData()
{
    final ProgressDialog pd = ProgressDialog.show(this,
            "Please wait", "Loading Data...", true, false);

    new Thread(new Runnable(){
        public void run(){
            employees = plh.deserializeEmployeeData();
            projects = poc.deserializeProjectData();

            // Check to see if data actually loaded, if not then refresh
            if ((employees == null) || (projects == null)) {
                refreshData();
            }

            // Load up pmList for spinner control
            pmList = employees.getPMList();

            pd.dismiss();
        }
    }).start();
}

private void refreshData()
{
    // Refresh data for Projects
    projects = poc.refreshData();
    poc.saveProjectData(mCtx, projects);

    // Refresh data for PMList          
    employees = plh.refreshData();
    plh.savePMData(mCtx, employees);
}
}

< ---- EDIT -----> Ich habe versucht, ändern onCreate (), um die folgende nach Jims Vorschlag. Nicht sicher, ob ich dieses Recht, immer noch nicht funktioniert :

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    mCtx = this;

    // Loads data from filesystem, or webservice if necessary
    // Would like to extend this to update if files are over x days old
    final ProgressDialog pd = ProgressDialog.show(this,
            "Please wait", "Loading Data...", true, false);

    new Thread(new Runnable(){
        public void run(){
            employees = plh.deserializeEmployeeData();
            projects = poc.deserializeProjectData();

            // Check to see if data actually loaded, if not then refresh
            if ((employees == null) || (projects == null)) {
                refreshData();
            }

            pd.dismiss();

            runOnUiThread(new Runnable() {
                public void run(){
                    // Load up pmList for spinner control
                    pmList = employees.getPMList();
                }
            });

        }
    }).start();

    spinner = (Spinner) findViewById(R.id.spinner);
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(
            this, android.R.layout.simple_spinner_item, pmList);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner.setAdapter(adapter);

    //---the button is wired to an event handler---
    Button btn1 = (Button)findViewById(R.id.btnGetProjects);
    btn1.setOnClickListener(btnListAllProjectsListener);
    spinner.setOnItemSelectedListener(new MyOnItemSelectedListener());
}

Wow, nahm dies für immer für mich eine Lösung zu finden, aber ich bin überglücklich, endlich diese bekommen zu arbeiten haben .

Aktualisieren der Spinner mit einem Hintergrundthread kann durch die Verwendung eines Handler durchgeführt werden. Der Handler wird aufgerufen, nachdem die Hauptarbeit des Gewindes ist abgeschlossen.

  mProgressDlg = ProgressDialog.show(this, "App_Name", "Loading data...", 
                                    true, false);
  new Thread(new Runnable(){
            public void run() {
                    /*Load Data, set pmList in my case*/
                    mProgressDlg.dismiss();
                    hRefresh.sendEmptyMessage(REFRESH);
            }
    }).start();



Handler hRefresh = new Handler(){

@Override
public void handleMessage(Message msg) {
   switch(msg.what){
     case REFRESH:
                 spinner = (Spinner) findViewById(R.id.spinner);
                 final ArrayAdapter<String> adapter = new ArrayAdapter<String>(
                         mCtx, android.R.layout.simple_spinner_item, pmList);
                 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
                 spinner.setAdapter(adapter);
                 spinner.setOnItemSelectedListener(new MyOnItemSelectedListener());
            break;
   }
}
};

Credits zum bhatt4982 und seine Antwort auf http://stackoverflow.com/questions/1458190/how-can-i-display-a-progress-at-start-up-application-in-android

---

Top 5 Antwort

1Jim Blackler @

Alle Arbeiten nach loaddata () in onCreate () getan werden muss, nachdem die Arbeit in run () in das Gewinde in loaddata ausgelöst () ist abgeschlossen. Versuchen inline loaddata () und das Hinzufügen dieser nach der Installation Arbeit zu einem runOnUiThread () nach pd.dismiss ().

2BJB @

Sie wissen nicht, ob Sie jemals gelöst haben, aber das funktioniert für mich :

public class Start extends Activity {
private static final String TAG = "PriceList";

ArrayAdapter<ProductCategory> category_adapter;
ArrayAdapter<ProductGroup> group_adapter;

ArrayList<ProductCategory> categories;
ArrayList<ProductGroup> groups;

ArrayList<Price> prices;

Spinner group_spinner;
Spinner category_spinner;
ProgressDialog progressDialog;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    group_spinner = (Spinner) findViewById(R.id.group_spinner);
    category_spinner = (Spinner) findViewById(R.id.category_spinner);

    // product category spinner
    categories = new ArrayList<ProductCategory>();

    category_adapter = new CustomArrayAdapter<ProductCategory>(categories);
    category_adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

    // load category spinner from database
    loadCategory();     // adapter MUST be setup before this is called

    category_spinner.setAdapter(category_adapter);
    category_spinner.setOnItemSelectedListener(new OnItemSelectedListener () {


    ..... other stuff ...... 


private final Handler handler = new Handler() {
    @Override
    public void handleMessage(final Message msg) {
        Log.v(TAG, "worker thread done, setup adapter");

        switch (msg.what) {
        case Constants.CATEGORIES:
            category_adapter.notifyDataSetChanged();
            break;
        case Constants.GROUPS:
            group_adapter.notifyDataSetChanged();
            break;
        case Constants.PRICES:
            startActivity(new Intent(Start.this, ShowPrices.class));
            break;
        default:
        }
        // dismiss dialog
        progressDialog.dismiss();
    }
};

    // loadCategory() essentially the same....

private void loadGroup(final String cat) {
    Log.v(TAG, "loadGroup");

    progressDialog = new ProgressDialog(this);
    progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    progressDialog.setMessage("Retrieving Product Groups...");
    progressDialog.setMax(100);
    progressDialog.setProgress(0);
    progressDialog.show();

    new Thread() {

        @Override
        public void run() {

            int count = 100;
            int i = 0;

            SQLiteDatabase db = DbUtils.getStaticDb();

            Cursor c = db.rawQuery("select count(*) from productgroup where category = '"
                            + cat + "';", null);
            c.moveToFirst();
            if (!c.isAfterLast()) {
                count = c.getInt(0);
            }
            c.close();

            progressDialog.setMax(count);

            groups.clear();
            groups.add(new ProductGroup("-1", "--- Select ---"));

            StringBuilder sb = new StringBuilder("select _id,description from productgroup");
            sb.append(" where category = '");
            sb.append(cat);
            sb.append("' order by description;");
            Log.v(TAG, sb.toString());

            c = db.rawQuery(sb.toString(), null);
            c.moveToFirst();
            while (!c.isAfterLast()) {
                Log.v(TAG, c.getString(0));
                groups.add(new ProductGroup(c.getString(0), c.getString(1)));
                i++;
                if (i % 5 == 0) {
                    progressDialog.setProgress(i);
                }
                c.moveToNext();
            }
            c.close();

            // tell UI thread OK
            handler.sendEmptyMessage(Constants.GROUPS);
        }
    }.start();
}

    // custom ArrayAdapter allows us to have our own ArrayList<T>

class CustomArrayAdapter<T> extends ArrayAdapter<T> {

    CustomArrayAdapter(ArrayList<T> list) {
        super(Start.this, android.R.layout.simple_spinner_item, list);
    }

}
3WareNinja @

Ich würde auch vorschlagen, die Sie verwenden https://github.com/commonsguy/cwac-task es hat sehr schöne AsyncTaskEx impl, die Sie verwenden, um schwere Arbeit tun, ohne Sperren der ui .

Example class;

protected class DoHeavyWorkAsync extends AsyncTaskEx<Void, Integer, String> {
        private static final String TAG = "DoHeavyWorkAsync";

        @Override
        protected String doInBackground(Void... arg0) {

            // do heavy work here. e.g. loadDataFromSomewhere();
            YourActivity.this.runOnUiThread(new Runnable() {
                public void run() {
                    // you can do ui work on the main activity from here
                }
            });

            return null;
        }

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

            Log.d(TAG, "onPreExecute()");
                    //e.g. display "loading..." 
        }
        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            Log.d(TAG, "onPostExecute()");
        }
    }

von Ihrer Haupttätigkeit Sie wie folgt aufrufen können ;

(new DoHeavyWorkAsync()).execute();