2012-06-12 27 views
11

Tôi có một Dịch vụ gửi Intent đến Hoạt động của tôi sau mỗi 0,1 giây. Tôi sử dụng nó để cập nhật một triển khai tùy chỉnh của một Chronometer. Ở đây mọi thứ diễn ra đúng. Vấn đề xảy ra khi tôi muốn cập nhật 14 TextView tôi có trong một TableView bên trong một Fragment trong hoạt động của tôi. Ở đây ứng dụng rất chậm.Nhiều TextViews cập nhật rất chậm

Phương pháp trong Hoạt động của tôi, nơi mà nó nhận được tiếp cận mục đích khỏi Dịch vụ:

private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     long milis = intent.getLongExtra("milis",0); 
     if(mFragment != null) 
     mFragment.Update(milis); 
    } 
}; 

Mã bên trong Fragment nơi tôi cập nhật các TextView:

public void actualizarTiempoJuego(long milis){ 
    // Se recuperan los tiempos acumulados y se aumenta la cantidad pasada como parámetro 
    for(int i=0;i<7;++i) { 
     long mCurrentMilis1 = mVectorMilis1.get(i); 
     long mCurrentMilis2 = mVectorMilis2.get(i); 
     TextView1 t1 = mListaTitularLayoutLocal.get(i); 
     TextView1 t2 = mListaTitularLayoutVisitante.get(i); 
     t1.setText(String.value(milis + mCurrentMilis1)); 
     t2.setText(String.value(milis + mCurrentMilis2)); 
    } 
} 

Tôi có làm điều gì sai trái, hoặc là nó chỉ là tôi đang cố gắng để làm một cái gì đó rất phức tạp về hiệu quả?

+0

tôi sẽ tạo ra một chuỗi từ 'milis 'và sử dụng nó 14 lần, thay vì cố gắng tạo ra 14 chuỗi giống hệt nhau. Và sau đó sử dụng các công cụ Android để kiểm tra xem một tiêu chuẩn cho vòng lặp, một vòng lặp cho mỗi hay sử dụng các Iterator cung cấp kết quả nhanh nhất. – Sam

+0

@Sam. Đây là một phiên bản nhẹ. Tôi đã sao chép ở đây như thế để dễ hiểu hơn. Tôi chỉnh sửa nó để làm cho nó hoàn chỉnh hơn. – gutiory

+0

Có thêm thông tin nào bạn muốn để chấp nhận câu trả lời không ?? –

Trả lời

7

@Sherif sẽ đưa ra một điểm tốt về các giá trị alpha ẩn làm giảm ứng dụng của bạn rất nhiều. Tùy thuộc vào nền tảng của bạn, bạn cũng có thể muốn kiểm tra

<application android:hardwareAccelerated="true"... /> 

Một điều bạn có thể nhìn vào đó có thể giúp thực hiện được không bắn ra tất cả những Intents. Một khi bạn bắt đầu bắn ý định bạn đang nhận được hệ thống liên quan và tùy thuộc vào cách họ đang nhận được giải quyết nó có thể mất một thời gian thêm.

Đối với vấn đề này tôi thích sử dụng Handlers. Chúng có trọng lượng nhẹ hơn ý định. Bạn cũng có thể xem AsyncTask. Điều này về cơ bản giống như một chuỗi, nhưng cũng cung cấp cho các móc chạy trên UI Thread để bạn có thể thực hiện cả hai thực hiện thao tác nền và cập nhật giao diện người dùng mà không phải đăng runnables.

EDIT: Cuối cùng, bạn luôn có thể chạy bố cục của mình thông qua công cụ layoutopt. Cá nhân tôi đã tự mình nói với Romain Guy rằng nếu bản vẽ của bạn quá chậm, bạn cần rút ra ít hơn. Chỉ cần kiểm tra một ảnh chụp màn hình (từ một cây xem ít lý tưởng hơn, nhưng cũng trong phạm vi tối đa) từ công cụ lược tả. Bạn có thể xem lượng bản vẽ chế độ xem tài nguyên mất bao nhiêu. Điều quan trọng là giữ cho điều này càng gọn gàng càng tốt nếu bạn muốn ứng dụng của mình phản hồi. Profiling View Drawing Resource Consumption

EDIT: Nó không còn được gọi là layoutopt, nó được gọi là lint. Kiểm tra ~/android-sdk/tools/

+0

HardwareAccelerated không giúp cải thiện hiệu suất. Tôi đang tìm công cụ Liên kết. Tôi sẽ nói với bạn sau. – gutiory

+0

Vâng. Tôi nói tăng tốc phần cứng có thể giúp, tùy thuộc vào nền tảng của bạn. Bạn cũng cần phải giới hạn bản vẽ và sử dụng ý định. Bạn đã nói với tôi sau này về công cụ liên kết nào? –

+0

Xin lỗi, tôi muốn nói công cụ lint. – gutiory

5

Tôi đã từng đối mặt với một tình huống trong đó một đoạn rất chậm.

Tôi chỉ dự đoán rằng đoạn của bạn có một số loại alpha và được vẽ trên hoạt động 'nặng'.

Kết luận là mỗi lần bạn đặt văn bản của một lần xem văn bản, toàn bộ hệ thống phân cấp chế độ xem của bạn sẽ bị vô hiệu.

Dường như các đoạn có lỗ hổng này. Dù sao, sử dụng một số bố trí thay vì mảnh và kiểm tra xem nó vẫn còn 'chậm'.


BỔ SUNG: Chế độ xem văn bản wrap_content sẽ gây trễ nhiều hơn sau một lần xem văn bản fill_parent.

+0

Nhận xét của bạn về wrap_content đang được giải quyết một vấn đề mà tôi đang gặp phải! Tiếng hoan hô! Cám ơn vì đã chia sẻ. – adrianmc

+0

Duuuuuude, bạn đã cứu mạng sống của tôi, cảm ơn bạn !!! Thay đổi chiều rộng của textView thành 'matchConstraint' đã thực hiện thủ thuật. Giao diện người dùng trở nên trơn tru và đáp ứng. – Mikhail

3

Bạn có thể gặp sự cố chậm do quản lý bố cục với TableLayout và TextView. Mỗi lần bạn cập nhật văn bản trong một trong số đó, một lượng lớn lượt xem phải diễn ra để đặt các ký tự ở đúng vị trí trên màn hình.Bạn nên thực sự chỉ cần tự mình ứng dụng bằng Traceview để tìm hiểu. Thông tin thêm tại: http://developer.android.com/tools/debugging/debugging-tracing.html

Tôi đã gặp sự cố tương tự chính xác mà bạn thấy với cùng một loại bố cục (Fragment> TableLayout> Multiple TextViews). Một cách để kiểm tra xem thiết lập TableLayout/TextView của bạn có đổ lỗi không đơn giản là thay thế tất cả bằng một TextView đơn lẻ. Điều đó có lẽ sẽ chạy khá tốt. Sau đó đặt 14 khung nhìn của bạn vào FrameLayout hoặc RelativeLayout. Ngay cả khi tất cả chúng đều chồng lên nhau, bạn vẫn nên có hiệu suất tốt, bởi vì đó là sự phức tạp của các phép đo xem TableLayout thực sự gây ra sự chậm lại.

+0

Tôi đã làm những gì bạn đã nói với tôi. Tôi bắt đầu với một TextView và everithing là đúng. Nhưng khi tôi thêm 5 TextView khác, nó trở nên chậm lại. – gutiory

+0

Bạn có xóa BảngLayout trước khi thử nghiệm này không?Tôi là 99% tích cực sự tụt hậu mà bạn thấy là từ việc đo lường Chế độ xem cần thiết để căn chỉnh đúng một số hàng của bố cục bảng kết hợp với việc đo TextView với văn bản động. – Josh

+0

Có. Tôi đã xóa TableLayout như bạn đã đề xuất. Tôi thay đổi mảnh bao gồm TableLayout cho các bản xem trước. – gutiory

0

Khi ai đó nói bạn có thể sử dụng HardwareAccelerated nhưng đây không phải là một giải pháp tuyệt vời, bạn sẽ lãng phí ram và CPU nếu bạn không thể giải quyết nó theo một cách khác. Một giải pháp có lẽ an toàn hơn là giảm số lượng TextView. Hãy thử giảm 14 đến 7 và nó sẽ nhanh hơn gấp hai lần. Thông thường là khó để làm điều đó, nhưng nếu bạn đặt các đối tượng trong một vị trí chiến lược một cặp TextView một ở trên khác có thể được với nhau nếu bạn thực hiện một TextView với hai dòng. Và đừng quên rằng findViewById là quá đắt, nếu bạn sẽ sử dụng một đối tượng xem thường tìm thấy nó một lần và giữ tham chiếu của nó.

0

Điểm chuẩn luôn hữu ích để xác định nơi chậm thực sự đến từ, nhưng tôi cảm thấy khá tự tin cho thấy rằng gửi Intent có lẽ chậm hơn nhiều so với việc cập nhật 14 TextViews. Gửi 10 Intents/giây là dấu hiệu cho thấy bạn đang làm việc đó sai (TM). Đây không phải là những gì họ đang làm.

Tôi có làm gì sai hay chỉ là tôi đang cố gắng làm điều gì đó rất phức tạp về hiệu quả?

Cập nhật 14 TextViews mỗi giây vốn không phức tạp; bạn sẽ có thể dễ dàng đạt được điều này với một thiết kế ứng dụng phù hợp hơn. ASyncTask hoặc Handler lưu ý đến các công cụ có thể, nhưng thật khó để biết điều gì là tốt nhất mà không biết rõ hơn về những gì bạn đang cố gắng làm.

+0

Tôi đã sử dụng Hanlder để cập nhật TextView nhưng tôi vẫn có hành vi tương tự. – gutiory

+0

@gutiory Bạn đã loại bỏ Dịch vụ và Mục đích? Việc thêm Trình xử lý lên trên điều đó sẽ không làm mọi việc nhanh hơn. Tôi đề xuất sử dụng kiến ​​trúc khác với Trình xử lý hoặc AsyncTask * thay thế * của Dịch vụ và Mục đích. –

0
  • Bạn có thể thử để khai báo VAR bên ngoài vòng lặp:

    public void actualizarTiempoJuego(long milis){ 
        // Se recuperan los tiempos acumulados y se 
        // aumenta la cantidad pasada como parámetro 
    
        long mCurrentMilis1; 
        long mCurrentMilis2; 
        TextView1 t1; 
        TextView1 t2; 
    
        for(int i=0;i<7;++i) { 
         mCurrentMilis1 = mVectorMilis1.get(i); 
         mCurrentMilis2 = mVectorMilis2.get(i); 
         t1 = mListaTitularLayoutLocal.get(i); 
         t2 = mListaTitularLayoutVisitante.get(i); 
         t1.setText(String.value(milis + mCurrentMilis1)); 
         t2.setText(String.value(milis + mCurrentMilis2)); 
        } 
    } 
    
  • Và để setText() với loại hỗn hợp, bạn có thể thử setText("" + milis + mCurrentMilis2);

+0

có thể là "onReceive" chặn ở đâu đó và sử dụng asynctask cho bản cập nhật giao diện người dùng cũng có thể tăng tốc quá trình – Arcadien