2010-12-14 43 views
5

tôi có một tiện ích cần thực hiện một hoạt động có khả năng hoạt động lâu dài trong onUpdate(). chỉ thực hiện các hoạt động trực tiếp dẫn đến ANR. để giải quyết vấn đề này, nỗ lực đầu tiên của tôi là tạo một chủ đề trong đó. tôi nhận thấy rằng tiện ích sẽ không được cập nhật trong một số trường hợp. đoán của tôi ở đây là một khi onUpdate() thoát, android có thể giết chết quá trình cùng với các chủ đề chưa hoàn thành.hoạt động lâu dài của Android để cập nhật appwidget

nỗ lực tiếp theo của tôi là tạo ra một dịch vụ có mục đích. onUpdate của tiện ích() chỉ bắt đầu dịch vụ ý định, công việc này trực tiếp và cập nhật tiện ích khi hoàn thành. điều này làm việc, nhưng nhiều đến ngạc nhiên của tôi nó xuất hiện rằng onHandleIntent() là đơn luồng. nếu tôi có hai tiện ích, sau đó cả hai cập nhật và bắt đầu dịch vụ ý định, chúng cập nhật tuần tự ...

hai trường hợp tiện ích không thực sự quan trọng, nhưng tôi tự hỏi về cách thực hành tốt nhất cho kiểu mẫu này .

để giải quyết hai trường hợp tiện ích, tôi đã kết thúc cập nhật tất cả các phiên bản tiện ích con với cùng một dữ liệu bất kỳ khi nào một trong số chúng được nhấp vào. ví dụ: tôi thực hiện quy trình chạy dài một lần và áp dụng kết quả cho tất cả các phiên bản tiện ích. trong kịch bản của tôi điều này không quan trọng, nhưng đối với nhiều vật dụng, điều quan trọng là không làm điều đó.

suy nghĩ?

Trả lời

3

nhưng trước sự ngạc nhiên của tôi có vẻ như onHandleIntent() là đơn ren

Yes.

nếu tôi có hai widget, và sau đó cả hai bản cập nhật và bắt đầu dịch vụ ý định, họ cập nhật liên tục ...

Yes.

nhưng tôi chỉ tự hỏi về cách thực hành tốt nhất cho kiểu mẫu này.

IntentService là giải pháp tốt nhất, IMHO. Hãy nhớ rằng Android chạy trên các CPU chậm, với các thiết bị có RAM nhỏ. Chạy nhiều luồng song song thường không phải là một ý tưởng hay.

sau đó tôi bắt đầu tạo chuỗi trong onHandleIntent(), yêu cầu khóa đánh thức và dường như quá phức tạp.

Hãy thử WakefulIntentService của tôi.

+0

okay nếu tôi hiểu bạn một cách chính xác. 1) widget bắt đầu ý định dịch vụ để có được dữ liệu và cập nhật widget khi nó được thực hiện 2) dịch vụ ý định được một khóa thức, và bắt đầu một thread để làm công việc thực tế, và sau đó cập nhật các widget khi nó được thực hiện 3) khi thread kết thúc, nó phát hành khoá. cậu bé nghe có vẻ phức tạp. tại sao tôi không thể lấy một khóa trong onHandleIntent()? –

+0

@ farble1670: Vì thiết bị có thể rơi vào giấc ngủ trước khi bạn đến đó. – CommonsWare

+0

xin lỗi, tôi có nghĩa là lấy một khóa trong onHandleUpdate(), trong appwidget impl. những gì không gửi yêu cầu đến một dịch vụ ý định mua cho tôi? –

0

make onUpdate gọi hàm của riêng bạn để chuyển qua các tiện ích và cập nhật chúng. Thực hiện tác vụ không đồng bộ của bạn trước chu kỳ. Bạn sẽ muốn có hai hành động riêng biệt, một hành động yêu cầu cập nhật bắt đầu và một hoạt động mà bạn sẽ phát sóng để cho các tiện ích biết rằng chúng đã hoàn tất. Hi vọng điêu nay co ich.

@Override 
public void onUpdate(Context context, AppWidgetManager appWidgetManager, 
     int[] appWidgetIds) { 
    updateWidget(context, appWidgetManager, appWidgetIds); 
} 

private void updateWidget(Context context){ 
    ComponentName widget = new ComponentName(context, MyWidget.class); 
    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); 
    int[] appWidgetIds = appWidgetManager.getAppWidgetIds(widget); 
    updateWidget(context, appWidgetManager, appWidgetIds); 
} 

private void updateWidget(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 

    final boolean isEnabled = true; //took out code didn't want you to see 
    // start intent service here 
    for(int i = 0; i< appWidgetIds.length; i++){ 
     int appWidgetId = appWidgetIds[i]; 
     Intent intent = new Intent(isEnabled ? ACTION_TOGGLE_OFF : ACTION_TOGGLE_ON); 
     PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0); 

     RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout); 
     views.setOnClickPendingIntent(R.id.widget , pi); 
     views.setImageViewResource(R.id.widget_image, isEnabled? R.drawable.widget_on : R.drawable.widget_off); 

     appWidgetManager.updateAppWidget(appWidgetId, views); 
    } 
} 
+0

hmmm, không chắc chắn tôi thấy cách áp dụng điều này. bắt đầu từ đầu. trong onUpdate(), thực hiện quy trình chạy dài, sau đó cập nhật tất cả các ID. quá trình chạy dài không thể chạy trong luồng onUpdate(), điều này sẽ gây ra ANR. vì vậy, hãy sử dụng dịch vụ ý định. nhưng đây là luồng đơn, vì vậy nếu nhiều cuộc gọi onUpdate() đến từ nhiều tiện ích, dẫn đến nhiều cuộc gọi dịch vụ có chủ ý, tiện ích con thứ hai bị treo chờ người đầu tiên kết thúc trong dịch vụ mục đích. –

+0

đây là lý do tại sao bạn sẽ gọi nó trước khi bạn chu kỳ và cập nhật các tiện ích của bạn, về cơ bản bạn tiếp quản thuyết phục google đã cập nhật tất cả các tiện ích cho bạn. Chức năng cập nhật nên thực sự chỉ xử lý các thay đổi giao diện người dùng, do đó bạn sẽ có câu lệnh if/else hoặc switch để xác định hành động hiện tại (bắt đầu chủ đề, tiến trình luồng, chuỗi đã hoàn thành) – schwiz

+0

okay ... câu hỏi đầu tiên của tôi đã bị bỏ lỡ là về việc bắt đầu chuỗi. nếu có thể bắt đầu một chuỗi trong onUpdate() và trả lại? tôi không cần phải lấy một khóa? android sẽ giết quá trình sau khi onUpdate() thoát? có nó bắt đầu một dịch vụ ý định thay cho một chủ đề dường như để ngăn chặn ANR nhưng nó không hoạt động khi có nhiều widget cập nhật khi họ sẽ treo chờ đợi onHandleIntent() để thoát. sau đó tôi đang bắt đầu một thread trong onHandleIntent(), đòi hỏi một khóa thức, và nó có vẻ như nó nhận được tất cả các quá phức tạp. –

Các vấn đề liên quan