0

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は私を助けてくれるか、これを達成するための他のオプションを提案してください。

4

1 に答える 1

0

メソッドを呼び出す

runOnUiThread(new Runnable(){
        public void run() {

                  write your method here 

        }
     });

メソッドからdoInbackground

于 2013-10-12T07:46:40.147 に答える