2012-12-21 18 views
5

Tôi có một ứng dụng Android thực hiện điều này:Giải quyết ý định cho URL là đôi khi null, ném NullPointerException

PackageManager pm = getApplicationContext().getPackageManager(); 
    Intent browserIntent = new Intent(); 
    browserIntent.setAction(Intent.ACTION_VIEW); 
    browserIntent.addCategory(Intent.CATEGORY_BROWSABLE); 
    browserIntent.setData(Uri.parse("http://www.google.com")); 

    ResolveInfo resolveInfo = pm.resolveActivity(browserIntent, PackageManager.MATCH_DEFAULT_ONLY); 
    try { 
     String browserType = nutent.activityInfo.packageName; 
    } catch (NullPointerException npe) { 
     npe.printStackTrace(); 
    } 

Tôi đã thử nghiệm này trên 4 điện thoại di động khác nhau và nhiều cấu hình giả lập khác nhau. Tất cả đều hoạt động tốt. Nhưng tôi nhận được báo cáo sự cố từ các ứng dụng được triển khai trong tự nhiên ném một NPE vì resolveInfo đôi khi là null.

Khắc phục ngay lập tức là bắt NPE và xử lý nó trước khi nó gặp sự cố ứng dụng của tôi (như đã làm ở trên). Nhưng tôi đã cố gắng nhiều ngày để tự mình tái sản xuất và không thể. Trên một giả lập với trình duyệt mặc định duy nhất được cài đặt, nó quyết tâm com.android.browser.BrowserActivity:

ResolveInfo{411ef228 com.android.browser.BrowserActivity p=0 o=0 m=0x208000} 

Tương tự, trên một chiếc điện thoại với nhiều trình duyệt được cài đặt, điều này giải quyết phần nào khác ... để com.android. internal.app.ResolverActivity:

ResolveInfo{415c13b8 com.android.internal.app.ResolverActivity p=0 o=0 m=0x0} 

các resolveActivity() docs here nhà nước:

Trả về một ResolveInfo chứa mục đích hoạt động chính thức đó là determ để trở thành hành động tốt nhất. Trả về null nếu không tìm thấy hoạt động nào phù hợp. Nếu tìm thấy nhiều hoạt động phù hợp và không có tập hợp mặc định, trả về một ResolveInfo có chứa một cái gì đó khác, chẳng hạn như trình phân giải hoạt động.

Vì vậy, tôi đã trình bày kịch bản đầu tiên, ý định hoạt động được xác định là hành động tốt nhất. Cũng là kịch bản cuối cùng, trong đó có nhiều hoạt động phù hợp không có hành động mặc định, trả về ResolverActivity.

Tôi thực sự muốn tạo lại kịch bản của resolveActivity() cho tôi một giá trị rỗng khi yêu cầu hoạt động của URL. Có ai có bất kỳ ý tưởng làm thế nào điều này có thể được thực hiện mà không có, nói, rễ thiết bị?

+0

Là một sang một bên, để "ăn" ngoại lệ như bạn làm là thực hành xấu. Các ngoại lệ được ném vì lý do chính đáng và khi bạn đang truy cập một tài nguyên bên ngoài, có nhiều lý do khiến nó có thể bị lỗi và mã của bạn nên xử lý chúng. – Simon

+0

Đây thực sự chỉ là một ý định "giả" chỉ được sử dụng để tìm nạp loại và phiên bản trình duyệt (nếu có), nó không bao giờ được sử dụng để truy xuất bất kỳ trang web nào hoặc làm bất cứ điều gì khác. Tôi tin rằng, trong trường hợp này, việc ăn ngoại lệ và đặt loại trình duyệt và chuỗi phiên bản của tôi thành "không xác định" là đủ. Không có gì khác tôi muốn làm với ngoại lệ. – AWT

+2

Câu hỏi hay. Tôi không biết chắc chắn, nhưng dự đoán của tôi là có thể bạn chưa bao gồm kịch bản cuối cùng "đó là nhiều hoạt động phù hợp không có hành động mặc định" mặc dù bạn nghĩ rằng bạn có, bởi vì bạn đang chỉ định MATCH_DEFAULT_ONLY. Tôi đã không crack nguồn của PackageManager (bước tiếp theo tốt), nhưng tôi tự hỏi nó sẽ làm gì nếu bạn bảo nó khớp với mặc định, và không có giá trị mặc định, trả về null?Bạn đã thử nghiệm trên một thiết bị hoặc trình giả lập với nhiều trình duyệt và KHÔNG CÓ DEFAULT? (Hãy đảm bảo rằng người chọn sẽ xuất hiện nếu bạn nhấp vào một liên kết, v.v.) –

Trả lời

0

Tôi thực sự muốn tạo lại kịch bản của resolveActivity() cho tôi giá trị rỗng khi yêu cầu hoạt động của URL. Có ai có bất kỳ ý tưởng nào về việc làm thế nào để thực hiện điều này mà không cần phải root thiết bị?

  1. Đến Cài đặt> Ứng dụng> ALL> Xác định vị trí (s) duyệt (trên Nexus 4 với chứng khoán ROM mà muốn được Chrome)> Disable
  2. Bắt đầu NPEs bắt :)
Các vấn đề liên quan