2016-03-11 40 views
0

我有ConcurrentLinkedQueue和队列在主线程中更新,并且AsyncTask显示ConcurrentLinkedQueue中的数据。它在第一次发射时可以正常工作。Android中主线程和AsyncTask之间的ConcurrentLinkedQueue使用情况

如果应用程序被后退键或主键停止,那么应用程序正在重新启动,问题就在那里。在主线程中,队列有数据,但在AsyncTask中,队列长度为零。

但是,应用程序被强制停止并重新启动,那就没事了。

这个Queue有什么问题?

我使用片段。

public class OneFragment extends Fragment implements SensorEventListener { 
    Queue<Float> queuex = new ConcurrentLinkedQueue<Float>(); 
    Queue<Float> queuey = new ConcurrentLinkedQueue<Float>(); 
    Queue<Float> queuez = new ConcurrentLinkedQueue<Float>(); 

    public void onCreate(Bundle savedInstanceState) { 
    } 

    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 

    } 
    @Override 
    public void onSensorChanged(SensorEvent event) { 
     queuex.add(Float.valueOf(deltaX)); 
     queuey.add(Float.valueOf(deltaY)); 
     queuez.add(Float.valueOf(deltaZ)); 

    } 

    protected class Update extends AsyncTask<Context, Integer, String> { 
    float x_,y,z; 
    @Override 
    protected String doInBackground(Context... params) { 

     int i = 0; 
     while (true) { 
      try { 
       if(!queuez.isEmpty()) { //Always zero after relaunch if the app is stopped by pressing home or back buttons. 

        Float g_x = queuex.poll(); 
        x_ = g_x.floatValue(); 
        Float g_y = queuey.poll(); 
        y = g_y.floatValue(); 
        Float g_z = queuez.poll(); 
        z = g_z.floatValue(); 
        publishProgress(i); 
        i++; 
        if(systemON == true) 
         mVibrator.vibrate(1000); 

       } 


      } catch (Exception e) { 

      } 
     } 
     //return "COMPLETE!"; 
    } 

    // -- gets called just before thread begins 
    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 

    } 


    @Override 
    protected void onProgressUpdate(Integer... values) { 
     super.onProgressUpdate(values); 

     mSeriesX.add(x, x_); 
     mSeriesY.add(x, y); 
     mSeriesZ.add(x++, z); 
     if(x%50 == 0) { 
      mRenderer.setXAxisMin(x); 
      mRenderer.setXAxisMax(x+50); 
     } 
     if (mChartView != null) { 
      mChartView.repaint(); 
     } 
    } 

    // -- called if the cancel button is pressed 
    @Override 
    protected void onCancelled() { 
     super.onCancelled(); 
    } 

    @Override 
    protected void onPostExecute(String result) { 
     super.onPostExecute(result); 
    } 
    } 
} 
+0

你在哪里实例化Update?也许可以考虑使用'队列'而不是三个队列。 – tynn

回答

1

首先,你不应该在AsyncTask中有无限循环。改用线程。事实上,如果你的任务需要超过几秒钟的时间,你应该使用一个线程,因为多个任务不能并发执行(默认实现是共享一个任务线程)。

其次 - 你的问题是由于任务永远运行的事实。这意味着前一项活动的任务(记得后退完成活动)在新活动启动时仍在运行。因此,您的旧任务仍在运行,并且可以访问Activity的旧实例 - 因此可以访问队列的旧实例。活动的新实例正在写入队列的新实例,但旧任务无法看到它。

您应该从AsyncTask移动到一个线程,以便您不会遇到单个任务问题。当你的活动被破坏时,你也应该中断线程,并且让线程检查中的循环isInterrupted来查看线程是否被中断,如果是这样,退出循环以杀死线程。

相关问题