android - Async Task 需要点击两次按钮才能完成加载

标签 android android-asynctask

下面是我的 LoginActivity 的代码,其中我基本上是从 URl 获取一个 JSON 和一个图像 在异步任务中。奇怪的是,我的 onClick() 的 else 部分总是执行(即 toast 显示)。只有当我再次单击该按钮时,它才会跳转到下一个 Activity 。

public class LoginActivity extends Activity
{

    Button getBunks;
    CheckBox detailscheck;
    EditText regText, bdayText;
    String storedReg, storedBDay;
    public static final String PREFS_NAME = "MyPrefsFile";
    String predataURL;
    String prephotoURL;
    public static URL dataUrl;
    public static String dataUri = "http://ankit.im/websisAPI/parser.php";
    ProgressDialog progressDialog;
    JSONObject temp = null;
    Bitmap tmpPhoto;
    boolean doneFlag = false;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        getBunks = (Button) findViewById(R.id.getBunkButton);
        detailscheck = (CheckBox) findViewById(R.id.rememberOpts);
        regText = (EditText) findViewById(R.id.regNo);
        bdayText = (EditText) findViewById(R.id.bday);
        detailscheck.setChecked(true); // To avoid Nag

        try
        {
            dataUrl = new URL("http://ankit.im/websisAPI/parser.php");
        } catch (MalformedURLException e)
        {
            e.printStackTrace();
        }

        // Check if login details are already stored

        SharedPreferences prefs = this.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        storedReg = prefs.getString("regno", null);
        storedBDay = prefs.getString("bday", null);

        // The Following Listeners Check if the user has entered
        // appropriate Data in the Fields
        // Check is on enter key press and on Focus Change

        SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
        final SharedPreferences.Editor editor = settings.edit();

        regText.setOnFocusChangeListener(new OnFocusChangeListener()
        {

            @Override
            public void onFocusChange(View v, boolean hasFocus)
            {
                if (detailscheck.isChecked())
                {
                    if (!hasFocus)
                    {
                        if (regText.getText().toString() != "" || regText.getText() != null)
                        {
                            editor.putString("regno", regText.getText().toString());
                            editor.commit();
                            // Toast.makeText(getApplicationContext(),
                            // "Reg No Stored", Toast.LENGTH_SHORT).show();
                        }
                    }

                }
            }
        });

        bdayText.setOnEditorActionListener(new OnEditorActionListener()
        {

            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
            {
                if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_DONE || event.getAction() == KeyEvent.ACTION_DOWN
                        && event.getKeyCode() == KeyEvent.KEYCODE_ENTER)
                {
                    editor.putString("bday", bdayText.getText().toString());
                    editor.commit();
                    // Hide Virtual Keyboard
                    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                    imm.hideSoftInputFromWindow(regText.getWindowToken(), 0);

                    return true;

                }
                return false;
            }
        });

        bdayText.setOnFocusChangeListener(new OnFocusChangeListener()
        {

            @Override
            public void onFocusChange(View v, boolean hasFocus)
            {
                if (detailscheck.isChecked())
                {
                    if (!hasFocus)
                    {
                        if (bdayText.getText().toString() != "" || bdayText.getText().toString() != null)
                        {
                            editor.putString("bday", bdayText.getText().toString());
                            editor.commit();
                            // Toast.makeText(getApplicationContext(),
                            // "BDay Stored", Toast.LENGTH_SHORT).show();
                        }
                    }

                }
            }
        });

        // Handle the button click
        getBunks.setOnClickListener(new OnClickListener()
        {

            @Override
            public void onClick(View v)
            {

                new DownloadStudentData().execute();

                if (doneFlag == true)
                {
                    // GlobalVars.showAttendanceData();
                    Intent actChange = new Intent(v.getContext(), DetailsTabViewActivity.class);
                    startActivity(actChange);
                    finish();
                } else if (doneFlag == false)
                {
                    Toast.makeText(getApplicationContext(), "Error in Downloading, Please Check Details or Try Again", Toast.LENGTH_LONG).show();
                }
            }
        });

    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    protected void onStart()
    {

        super.onStart();
        if (storedReg != null && storedBDay != null)
        {
            regText.setText(storedReg);
            bdayText.setText(storedBDay);
        }

    }

    private class DownloadStudentData extends AsyncTask<Void, Void, Void>
    {
        // ProgressDialog progressDialog;
        final JSONParser jsp = new JSONParser();

        @Override
        protected void onPreExecute()
        {
            // super.onPreExecute();
            progressDialog = new ProgressDialog(LoginActivity.this);
            progressDialog.setCancelable(true);
            progressDialog.setTitle(" Downloading Data ");
            progressDialog.setMessage("Please Wait, Loading...");
            progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            // progressDialog.setProgress(0);
            progressDialog.show();

        }

        @Override
        protected Void doInBackground(Void... voids)
        {

            temp = new JSONObject();
            temp = jsp.getJSONFromUrl(dataUri); // get the data
            prephotoURL ="http://218.248.47.9/websis/control/img/P12703.JPGimgId=P12703";

            try
            {
                InputStream in = new java.net.URL(prephotoURL).openStream();
                tmpPhoto = BitmapFactory.decodeStream(in);
            } catch (Exception e)
            {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }

            return null;
        }

        protected void onPostExecute(Void v)
        {

            GlobalVars.setJSON(temp);
            GlobalVars.setPhotoURL(prephotoURL);
            GlobalVars.setBitmap(tmpPhoto);
            doneFlag = true;

            try
            {
                GlobalVars.setPhotoURL(temp.getString("photolink"));
            } catch (JSONException e)
            {
                e.printStackTrace();
            }

            progressDialog.dismiss();
        }
    }

    @Override
    protected void onPause()
    {
        super.onPause();
        if (progressDialog != null)
            progressDialog.dismiss();
    }
}

GlobalVars 只是一个包含公共(public)静态变量和方法的全局类。

另外我不确定这是否是在后台从 URL 下载图像的正确方法,任何更好的替代方法将不胜感激(URLImageViewHelper 不适合我的需要)。

最佳答案

AsyncTask 在不同的线程上运行,并且不会及时完成以更改 doneFlag 的值。 (这就是为什么它是异步的。)

new DownloadStudentData().execute(); // Takes time to complete

if (doneFlag == true) { ... } // Happens milliseconds later, AsyncTask still running
else if (doneFlag == false) { ... } 

您需要在 onPostExecute() 中运行任何“完成”代码。


一些快速提示:

  • if (doneFlag)if (doneFlag == true) 的简写。
  • 一个 bool 值只能有两种状态,你不需要使用else if(),只需使用else {...}

关于android - Async Task 需要点击两次按钮才能完成加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15934754/

相关文章:

Android 将 GridView 与 OnScrollListener 结合使用

android - 以编程方式更改线性布局上边距android

android - ActionBar 选项卡删除填充和分隔符

方向更改时的 Android ActionBar Tabs 行为

Android Volley 发布请求。如何设置实体?

android - 在回收站 View 中更新微调器

android - 异步任务结束后开始 Intent

java - 如何处理执行 doInBackground() 时发生错误的异常

android - looper 到 "quit"哪里?

java - Android - loopJ AsyncHttpClient 返回响应 onFinish 或 onSuccess