Использование Android AsyncTask и уведомлений, которые замораживают мою систему
Я просто хотел научиться делать некоторые разработки для Android-приложений, поэтому я начал с простых демонстраций, а теперь делал что-то сложнее (наверное;-)).
Использование: Eclipse + min SDK 8 + Android 2.2. Отладка и тестирование на эмуляторе и моем SGS I9000:
Мне удалось использовать AsyncTask для отправки некоторых данных (изображения, которые я получаю с камеры или через галерею) на сервер, который прекрасно работает. Итак, теперь, когда все работает отлично, я решил добавить пользовательское уведомление в строку состояния с индикатором выполнения и текстом. Ну, это тоже сработало, но потом я заметил:
1) как только я позвоню publishProgress()
от doInBackground()
который назовет onProgressUpdate()
где я обновляю свое уведомление. При открытии и закрытии панели уведомлений во время обновления я заметил, что она не гладкая. Он зависает или когда-нибудь вы увидите, что панель уведомлений больше не отвечает (если она открыта, она больше не будет закрываться или если она была закрыта и попытаться открыть ее не будет).
2) Я также заметил, что когда я запускаю x Уведомления, происходит сбой моей Системы, и похоже, что моя система начала новый запуск, чего не произошло!
ну, я думал, что я сделал все как есть в документации, но я уверен, что я сделал что-то не так, потому что я уверен, что это возможно, что я ищу, так как Facebook для Android делает то же самое, что и я, как только я выбираю картинку для доля.
Я создаю уведомление в моем onPreExecute()
вызов (так что это означает в потоке пользовательского интерфейса).
вот мой код, если кто-нибудь может сказать мне, где моя проблема: (я надеюсь, что это нормально, чтобы опубликовать код здесь) NotificationHelper управляет уведомлением путем генерации и обновления индикатора выполнения / текста
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();
}
}
Извините, если это слишком много кода, но я на самом деле в конце моего понимания!
Интересно, что когда я не называю publishProgress()
ничего не зависает и выглядит все гладко! Любая помощь? Любая идея, что я делаю не так?
Большое спасибо заранее, Cheers Gohlool
1 ответ
Я думаю, что когда бы вы ни называли свой код асинхронной задачи, он должен быть в отдельном потоке.