私はちょうどこれを手に入れましたが、うまくいく順番に小さな問題があります。具体的には、thread() で、Spinner によって使用される配列を設定しています。問題は、Spinner がすべて設定され、基本的に thread() が終了する前に完了するため、null 配列で設定されることです。
スピナー ArrayAdapter を、別のスレッドによってロードされている配列に関連付けるにはどうすればよいですか?
問題を理解するために必要と思われるコードを切り詰めましたが、さらに必要な場合はお知らせください。この問題は、refreshData() が呼び出されるかどうかに関係なく発生します。
同様に、メニューから loadData() を呼び出したい場合もあります。次の行でトーストを起動しようとすると、loadData() の直後に続くと、forceclose が発生します。これは、ProgressDialog の実装方法にも起因します。
ご覧いただきありがとうございます
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 -----> Jims の提案の後、onCreate() を次のように変更してみました。私がこれを正しく行ったかどうかはわかりませんが、まだ機能しません:
@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());
}
うわー、これは私が解決策を見つけるのに永遠にかかりましたが、ついにこれが機能するようになったことに大喜びしています.
バックグラウンド スレッドで Spinner を更新するには、ハンドラーを使用します。ハンドラーは、スレッドの主な作業が完了した後に呼び出されます。
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;
}
}
};
bhatt4982 の功績とこのスレッドでの彼の回答