【问题标题】:Executing AsyncTask in Button Click without Crash or Exception在按钮单击中执行 AsyncTask 没有崩溃或异常
【发布时间】:2015-12-17 10:29:08
【问题描述】:

我看到了很多重复的问题(herehereherehere),但我的问题没有得到解决。

这是我的应用程序的想法

url 获取内容并在每个按钮点击 上使用textview 显示它。

(网址内容会每次刷新都会随机生成不同的文字


This 是我的应用程序的旧代码,它运行良好,但 StackOverflow 人建议我使用 AsyncTask

我在 doInBackground() 方法中指定了获取 URL 内容操作,并在 onCreate 的 Button Click 事件中调用了 new myAsyncTask.execute()。

只对第一次点击起作用,然后我的应用程序崩溃了。它说 AsyncTask 应该只调用一次。但我希望我的 TextView 在每个按钮单击事件上更新。


那么,我现在该怎么办

我是否想取消我之前的 AsyncTask 并调用新的(或) 我想为 AsyncTask 初始化新对象并再次调用它(这是最糟糕的方法)

如何使用 AsyncTask 或任何 Alternate 在我的应用中实现我的想法?

这是我的代码:

public class MainActivity extends AppCompatActivity {

    TextView resultView;String TAG="MainActivity kbt";
    SmoothProgressBar mProgressBar;
    Context context;
    MyAsyncTask myAsyncTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
      //  StrictMode.enableDefaults();  //Used to executes URL connection on MainThread without getting Exception
        setContentView(R.layout.activity_main);
        mProgressBar = (SmoothProgressBar) findViewById(R.id.progressBar);
       StrictMode.enableDefaults();
        resultView = (TextView) findViewById(R.id.result);
        myAsyncTask=new MyAsyncTask();
       // mProgressBar.setVisibility(SmoothProgressBar.INVISIBLE);


        Button insert=(Button) findViewById(R.id.button);
        insert.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                // TODO Auto-generated method stub
                myAsyncTask.execute();

            }
        });
    }   

    private class MyAsyncTask extends AsyncTask<Void, Void, Void> {
        String mTAG = "myAsyncTask";

        @Override
        protected void onPreExecute() {
           mProgressBar.progressiveStart();
        }

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

            try {
                getData();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }


        @Override
        protected void onPostExecute(Void a) {
            mProgressBar.progressiveStop();
        }
    }

 public void getData() throws IOException {

        String result = "";
        InputStream isr = null;  

        URLConnection urlConnection = null;
        URL url = new URL("http://kbtganesh.16mb.com/index.php");
        Log.d(TAG,"After  URL NOT WORKING");   //AFTER THIS.... NEXT LOG (ie GOT URL CONNETION) IS NOT PRINTED

        urlConnection =  url.openConnection();

        Log.d(TAG, "GOT URL CONNETION");

        Log.d(TAG, "GOT URL CONNECTED");
        isr =urlConnection.getInputStream();
        Log.d(TAG,"AFTER ISR EQ");



        //convert response to string

        try {
           // BufferedReader reader = new BufferedReader(new InputStreamReader(isr,"iso-8859-1"),8);
            BufferedReader reader = new BufferedReader(new InputStreamReader(isr));
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            isr.close();

            result=sb.toString();
        }
        catch(Exception e){
            Log.e("log_tag", "Error converting result "+e.toString());
        }

        //parse json data
        try {
            resultView.setText(result);
        }
        catch(Exception e) {
            Log.e("log_tag", "Couldn't set text, damnit.");
        }

    }

}

在此先感谢...(:

【问题讨论】:

  • 每次你想运行它时,只需创建一个新的 AsyncTask 实例。如果你不能让它工作,你必须发布你的代码让我们帮助你。
  • 发布您的代码以提供帮助。
  • 是的,对不起,我之前忘记粘贴了
  • myAsyncTask=new MyAsyncTask(); 移动到 onClick() 方法的开头。
  • 请忽略commentsLogCat 消息,因为我从各个地方复制代码。

标签: android android-asynctask


【解决方案1】:

在 StackOverflow 朋友的帮助下,我终于找到了我的问题的解决方案。

onClick() 中移动myAsyncTask=new MyAsyncTask(); 方法解决了我的问题。这是多次执行 AsyncTask 的最佳方式。

AsyncTask 实例在执行完毕后最终会被垃圾回收。因此我们无需担心创建多个实例。它们将被自动丢弃。

MyAsyncTask myAsyncTask;
insert.setOnClickListener(new View.OnClickListener() {

        @Override 
        public void onClick(View view) {
            // TODO Auto-generated method stub 
            myAsyncTask=new MyAsyncTask();
            // TODO Auto-generated method stub
           myAsyncTask.execute();


        } 
    }); 

【讨论】:

    【解决方案2】:

    我看到了您使用 StrictMode.enableDefaults(); 的旧帖子。艾米·卡普斯也说过。

    我可以接受应用程序不会崩溃,但出于多种原因,最好使用 AsyncTask。您可以轻松实现 progressbar 以指示后台进程等。

    onClick() 中简单地启动实例会更好。

    【讨论】:

    • 是的,在使用异步任务时实现进度条非常简单
    【解决方案3】:

    您不能多次执行同一个 AsyncTask 实例。

    您可以简单地在普通函数中使用它,并在 onCreate() 的开头指定StrictMode.enableDefaults();。那么应用程序就不会因为任何异常而崩溃。

    【讨论】:

      【解决方案4】:

      每当您想调用execute() 时,您都必须创建 AsyncTask 类的新实例(对象)。例如(new MyAsyncTask()).execute();

      【讨论】:

        【解决方案5】:

        如果正在运行则取消上一个任务并通过执行开始新任务

        if (myAsyncTask!= null && myAsyncTask.getStatus() == MyAsyncTask.Status.RUNNING) { 
              myAsyncTask.cancel(true);
        }
        myAsyncTask.execute();
        

        【讨论】:

          猜你喜欢
          • 2018-10-13
          • 1970-01-01
          • 1970-01-01
          • 2021-03-13
          • 2012-02-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多