Androidアプリでスレッドを使用する際に問題に直面していました。
SQL lite データベースからデータを取得し、アクティビティに表示する関数を持つ Activity1.java があります。スピナー static と database からのいくつかを満たす Load() メソッドが 1 つあります。2 番目のスピナーの値は、最初のドロップダウンに依存します。また、一部の UI コントロールを表示/非表示にします
シナリオ 1 :-
oncreate() メソッドで Load() 関数を呼び出すと、アクティビティが遅くなります。
シナリオ 2 :- (スレッド)
oncreate() メソッドのスレッド内で Load() 関数を呼び出し、runOnUiThread または Handler.post を使用して UI コントロールを更新すると、そのコードがスキップされ、コードをさらに進めて、他の値が間違っているか、適切に取得されません。 .
シナリオ 3 :- (非同期)
oncreate() Method で Aysnc 内の Load() 関数を呼び出すと、async task から ui を継続的に更新する必要があります。UI での更新は onPostExecute(Result) および onProgressUpdate(Progress...) でのみ許可されますが、async から継続的に UI を更新する方法を教えてください。
@Override
protected void onCreate(Bundle savedInstanceState) {
BindStaticValues();
GetCalculationOptions();
}
public void BindStaticValues()
{
//standard
BindStandard(); //static spinner (not db)
//Spinner 1
array1 = new ArrayList<ObjectMaterial>();
Adapter1 = new DescriptionAdapter(this,
android.R.layout.simple_spinner_item,
array1 );
Adapter1
.setDropDownViewResource(android.R.layout.simple_spinner_item);
sp1.setAdapter(Adapter1 );
//Spinner 2
array2 = new ArrayList<ObjectMaterial>();
Adapter2 = new DescriptionAdapter(this,
android.R.layout.simple_spinner_item,
array2 );
Adapter2
.setDropDownViewResource(android.R.layout.simple_spinner_item);
sp2.setAdapter(Adapter2 );
}
public void GetCalculationOptions ()
{
progressCalcualtionOptions = ProgressDialog.show(context, getString(R.string.progressCalcualtionOptionsTitle),
getString(R.string.progressCalcualtionOptionsMessage), true);
new Thread(new Runnable() {
public void run() {
try
{
LoadValuesforFirstTime(false, false, false); //main load method (Need Updating UI)
isFirstOpen=false;
}
catch (Exception e) {
//Log.d(Constants.TAG, e.getMessage());
e.printStackTrace();
}
if (progressCalcualtionOptions != null)
{
progressCalcualtionOptions.dismiss();
progressCalcualtionOptions=null;
}
}
}).start();
}
private void LoadValuesforFirstTime(Boolean FromMaterial,
Boolean FromLangugae, Boolean FromCountry) {
ChangeVisibility(); // it will change visibility of some controls
FillSpinner1(TypeofMaterial); //fill first spinner 1
FillSpinner2(ObjectMaterial); //fill first spinner 2 (take values from spinner 1 or manipulate values in spinner 1)
}
private void ChangeVisibility() {
// it will change visibility of some controls
runOnUiThread(new Runnable() {
public void run() {
relat_heightPipe.setVisibility(View.GONE);
relat_PipeDiameter.setVisibility(View.GONE);
relat_WidthPipe.setVisibility(View.GONE);
relat_length.setVisibility(View.GONE);
relat_lblMediumHeatCapacity.setVisibility(View.GONE);
relat_lblMediumDensity.setVisibility(View.GONE);
}
});
}
private void FillSpinner1(String TypeofMaterial) {
array1 = DB_Manager.All(); //get from db
h.post(new Runnable() {
public void run() {
Adapter1.clear();
for (ObjectMaterial object : array1 )
Adapter1.add(object);
Adapter1.notifyDataSetChanged();
}
});
}
private void FillSpinner2(String TypeofMaterial) {
array2 = DB_Manager.All1(spinner1.getSelectedItemPosition()); //get from db
h.post(new Runnable() {
public void run() {
Adapter2.clear();
for (ObjectMaterial object : array2 )
Adapter2.add(object);
Adapter2.notifyDataSetChanged();
}
});
}
今、問題は:-
アクティビティが開くと、GetCalculationOptions はスレッドを呼び出してすべてのスピナー値を入力します。これで LoadValuesforFirstTime() 関数を呼び出します。ここでは、 db と ui ですべてのことを行います。ここで changevisibility いくつかのコントロールの可視性を変更します。FillSpinner1 は db から値を取得し、メイン UI スレッド内のアダプタを更新します。Spinner2 は、スピナー 1 で選択された値に従って db から値を取得しますが、それまでは値が満たされていないため、スピナー 1 には値が見つかりません。今は別のスレッドです。ここで、LoadValuesforFirstTime() 関数から継続的に UI を更新する必要があります。
誰でも、plzは私を助けてくれるか、これを達成するための他のオプションを提案してください。