3

ネットワーク呼び出しを待っている間に、非常に単純なローディング ホイールを実装しようとしていたので、非常にイライラしています私は何十ものSOの質問を検索して読んだことがあります. AsyncTaskルートをたどってみましたが、それは私が望むものではありません。

また、現在、私のアプリは完全に機能していますが、ネットワーク上で待機しているときに、画面から画面への遷移がハングしているように見えるだけです。ユーザーがアプリが動作していてフリーズしていないことを1〜2秒で知ることができるように、ロードホイールが必要です。

現在のネットワーク呼び出しは次のようになります。

 private static String sendDataToServer(String arg1, String arg2)
 {        
    Thread dbThread = new Thread()
    {
        public void run()
        {
             // do the call that takes a long time    
        }
    };
    dbThread.start();
    try {
        // I do this so that my program doesn't continue until
        // the network call is done and I have received the information
        // I need to render my next screen
        dbThread.join();
    }
    catch (InterruptedException e) {
        e.printStackTrace();
    }
 }

では、なぜProgressDialogこのように追加できないのでしょうか。これを行うと、progressDialog は表示されません。

 private static String sendDataToServer(String arg1, String arg2)
 {
    final ProgressDialog progress = new ProgressDialog(BaseActivity.getInstance());
    progress.setIndeterminate(true);
    progress.setMessage("Loading...");
    progress.show();

    Thread dbThread = new Thread()
    {
        public void run()
        {
             // do the call that takes a long time    
        }
    };
    dbThread.start();
    try {
        dbThread.join();
        progress.dismiss();
    }
    catch (InterruptedException e) {
        e.printStackTrace();
    }
 }

ネットワーク呼び出しは UI スレッドとは別のスレッドで行う必要があるため、行き詰まっていると思いますが、続行するにはその呼び出しの結果が必要なため、アプリケーションを続行したくありません。しかし、私がそうするなら、私はthread.join()すべてを保持します。必要だと思ってAsyncTaskいましたが、すぐに下り坂になりました。興味があれば、これが私の質問です。 Android の AsyncTask: 複数のパラメーター、戻り値、待機

この呼び出しが発生しているときに、アプリケーションの残りの部分を続行せずに、読み込みダイアログを表示するだけです。

編集

これが私のAsyncTask試みです。

private class PostToFile extends AsyncTask<PostToFile, Void, Void>{
    private String functionName;
    private ArrayList<NameValuePair> postKeyValuePairs;
    private String result = "";

    public PostToFile(String function, ArrayList<NameValuePair> keyValuePairs){
        functionName= function;
        postKeyValuePairs = keyValuePairs;
    }

    @Override
    protected void onPreExecute() {
        progressDialog = ProgressDialog.show(BaseActivity.getInstance(), "Loading", "Please wait...", true, false);
    }

    @Override
    protected Void doInBackground(PostToFile... params) {                       
        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        nameValuePairs.add(new BasicNameValuePair(FUNCTION_KEYWORD, functionName));
        for (int i = 0; i < postKeyValuePairs.size(); i++)            {
            nameValuePairs.add(postKeyValuePairs.get(i));
        }

        try{
            // ***do the POST magic.***
            result = response.toString();
        }
        catch (Exception e){
             // clean up my mess
        }

        return null;
    }

    private String getResult(){
        return result; // can I use this somehow???
    }

    @Override
    protected void onPostExecute(Void result) {
        progressDialog.dismiss();
    }
 }

そして、私がそれを使用するとき:

        new PostToPHP(FUNCTION_NAME, postPairings){
            @Override
            protected void onPostExecute(String result) {
                super.onPostExecute(result);
                try
                {
                    if (result != null && !result.startsWith("null"))
                    {
                        JSONArray jArray = new JSONArray(result);
                        parseData(jArray);
                    }
                }
                catch (JSONException e)
                {
                    Log.e(Constants.LOG_TAG, e.toString());
                }
            };
        }.execute()

問題は、これらの呼び出しが連続していくつかあり、それぞれが互いに依存していることです。したがって、最初の 1 つが開始され、最初の 1 つが開始された直後に 2 つ目が開始されますが、最初の 1 つが終了する前に. だから私は間違った行動をします。最初の通話が完全に終了した後でのみ、2 番目の通話を開始するにはどうすればよいですか?

4

2 に答える 2

2

多分これはうまくいくでしょう、私はテストしていませんが、試すことができます:

public class MyTask extends AsyncTask<String, Void, String> {
    private int flag;


    public MyTask(int flag) {
        this.flag = flag;
    }


    @Override
    protected String doInBackground(String... params) {
        switch (flag) {
            case 1:
                return doNetworking1();
            break;
            case 2:
                return doNetworking2();
            break;
            case 3:
                return doNetworking3();
            break;
            default:
                return doNetworking1();

        }
    }

    @Override
    protected void onPreExecute() {
        //show progress dialog
    }

    @Override
    protected void onPostExecute(String s) {
        //hide progress dialog
        switch (flag) {
            case 1: //do something with result
                new MyTask(2).execute();
                break;
            case 2: //do other stuff
                new MyTask(3).execute();
                break;
            case 3: //do event more stuff
                break;
            default:
                //do something
        }
    }
}

と使用法:

new MyTask(1).execute();
于 2013-03-02T21:28:58.453 に答える
1

ネットワーク接続の場合は、のIntentService代わりに使用しAsyncTaskます。

たとえば、ネットワーク接続用のIntentServicesを作成します。

 public class NetworkCallIntentService extends IntentService {
    public static final String BROADCAST_ACTION = "com.yourpackage:NETWORK_CALL_BROADCAST";
    public static final String RESULT = "com.yourpackage:NETWORK_CALL_RESULT";

    public NetworkCallIntentService() {
        super(NetworkCallIntentService.class.getSimpleName());
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        // get data from intent if needed
        // do the call that takes long time  
        // send broadcast when done
        Intent intent = new Intent(BROADCAST_ACTION);
        intent.putExtra(RESULT, "some_result");//and more results
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
    }
}

次に、アクティビティからそのサービスを開始し、進行状況ダイアログを表示し、次の画面を表示するためのコードをBroadcastReceiver#onReceive()メソッドに移動します。

 public class SomeActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //start service
        Intent serviceIntent = new Intent(this, NetworkCallIntentService.class);
        //put extras into intent if needed
        //serviceIntent.putExtra("some_key", "some_string_value");
        startService(serviceIntent);
        //here just show progress bar/progress dialog
    }

    @Override
    protected void onResume() {
        super.onResume();
        LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(mNetworkCallReceiver,
                new IntentFilter(NetworkCallIntentService.BROADCAST_ACTION));
    }

    @Override
    protected void onPause() {
        super.onPause();
        LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(mNetworkCallReceiver);
    }

    private BroadcastReceiver mNetworkCallReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            //hide progress bar/progress dialog
            //here get results from intent extras
            String result = intent.getStringExtra(NetworkCallIntentService.RESULT);
            //process results and continue program(go to next screen, show error message etc.)
        }

    }

}

マニフェストファイルでサービスを宣言します。

<service
    android:name="com.yourpackage.DownloadSvtValuesIntentService"
    android:exported="false" >
</service>
于 2013-03-02T22:20:52.607 に答える