使用Android AsyncTask和Notification冻结我的系统

时间:2011-05-16 13:19:43

标签: android android-asynctask android-notification-bar

我只是想学习如何进行一些Android App开发,所以我从一些简单的演示开始,现在做一些更难的事情(我想;-))。

使用:Eclipse + min SDK 8 + Android 2.2。在模拟器和我的SGS I9000上进行调试和测试:

我设法使用AsyncTask将一些数据(我从相机或图库中获取的图片)发送到效果很好的服务器。所以,既然事情很好,我决定在状态栏中添加一个带有进度条和文本的自定义通知。嗯,这也有效,但后来我注意到了:

1)我尽快打电话给来自publishProgress()的{​​{1}},这会调用doInBackground()我更新通知的地方。我注意到在更新期间“打开”和“关闭”通知栏,它不顺畅。它会冻结或者有时您会看到通知栏不再响应(如果打开它将不再关闭或者如果它已关闭并尝试打开它不会)。

2)我也注意到当我启动x Notifications时,我的系统崩溃了,看起来我的系统没有新的启动,但它没有!

好吧,我认为我做了文件中的所有内容,但我确信我做错了什么,因为我确信我可能正在寻找的东西,因为Facebook for Android的做法和我选择的一样快要分享的图片。

我在onProgressUpdate()调用中创建通知(这意味着在UI线程上)。

这里是我的代码,如果有人可以告诉我我的问题在哪里:(我希望可以在这里发布代码) NotificationHelper通过生成和更新进度条/文本

来管理通知
onPreExecute()

这是我的任务:

public class NotificationHelper {

     private Context mContext;
     private Notification mNotification;
     private NotificationManager mNotificationManager;
     private PendingIntent mContentIntent;
     private RemoteViews contentView;
     private static Random randomGenerator = new Random();
     private int Id = -1;

     public NotificationHelper(Context context)
     {
         mContext = context;
         Id = randomGenerator.nextInt(1000);
     }

     public void CreateNotification(String text)
     {
         mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
         mNotification = new Notification(R.drawable.icon, "MyTestApp", System.currentTimeMillis());
         contentView = new RemoteViews(mContext.getPackageName(), R.layout.notification);
         contentView.setProgressBar(R.id.progressBar, 100, 0, false);        
         contentView.setTextViewText(R.id.text, Html.fromHtml("<b>TEST </b>" + text));
         contentView.setTextViewText(R.id.textStatus, String.format(mContext.getString(R.string.uploading), ""));
         mNotification.contentView = contentView;

         Intent notificationIntent = new Intent(mContext, main.class);
         notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         mContentIntent = PendingIntent.getActivity(mContext, 0, notificationIntent, 0);
         mNotification.contentIntent = mContentIntent;
         mNotificationManager.notify(Id, mNotification);
     }

     public void UpdateProgress(int Percent)
     {
         if (mNotification == null) return;
         mNotification.contentView.setProgressBar(R.id.progressBar, 100, Percent, false);
         contentView.setTextViewText(R.id.textStatus, String.format(mContext.getString(R.string.uploading), Integer.toString(Percent) + "%"));
         mNotificationManager.notify(Id, mNotification);
     }

     public void Completed(boolean Status)
     {
         if (contentView != null) {
             //mNotificationManager.cancel(Id);
             contentView.setViewVisibility(R.id.progressbarContainer, View.INVISIBLE);
             if (Status) 
             {
                 contentView.setTextViewText(R.id.textStatus, mContext.getString(R.string.upload_done));
             }else
             {
                 contentView.setTextViewText(R.id.textStatus, mContext.getString(R.string.upload_failed));
             }
             mNotificationManager.notify(Id, mNotification);
         }
     }

}

这是我的测试活动:

public class MyTask extends AsyncTask<Void, Integer, Integer> {

    private Context context;
    private NotificationHelper pbNotificationHelper;
    public String TextToShow;

    public MyTask(Context context, String text) {
        this.context = context;
        TextToShow = text;
    }

    @Override
    protected Integer doInBackground(Void... params) {

        int xfileSize = 1048576 * 4;
        if (true){
            int i = 0;
            while (true)
            {
                if (i > xfileSize) break;
                i += 32 * 1024;
                publishProgress( (i * 100) / xfileSize);
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        return 0;
    }

    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        super.onPreExecute();
        pbNotificationHelper = new NotificationHelper(context);
        pbNotificationHelper.CreateNotification(TextToShow);
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        // TODO Auto-generated method stub
        super.onProgressUpdate(values);
        pbNotificationHelper.UpdateProgress(values[0]);
    }

    @Override
    protected void onPostExecute(Integer result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        pbNotificationHelper.Completed(true);
    }
}

如果代码太多,我很抱歉,但我的理解已经结束了!

有趣的是,当我不打电话给public class main extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } public void Test1Click(View view) { new MyTask(getApplicationContext(), "This is a test message").execute(); } } nothings冻结并看起来一切顺利!有帮助吗?任何想法我做错了什么?

非常感谢, 干杯Gohlool

1 个答案:

答案 0 :(得分:0)

我认为无论你在哪里调用异步任务代码,都应该在单独的线程中。