Làm việc xung quanh ADB và chờ đợi vấn đề về thiết bị


9

Chúng tôi đang thiết lập một máy chủ tích hợp liên tục để phát triển Android và chúng tôi đã nhanh chóng gặp phải sự cố về thiết bị của ADB .

Đối với hồ sơ, chúng tôi đã cố gắng rất nhiều sự kết hợp của adb kill-server, adb start-server, adb devices, vv để vô ích.

Đáng buồn thay, tất cả những gì tôi tìm thấy trên internet là các biến thể của "rút phích cắm và cắm lại thiết bị", đây rõ ràng không phải là một giải pháp cho chúng tôi (chúng tôi không thể cho phép một người ngồi trước máy chủ CI để rút và cắm lại thiết bị trước đó mỗi bản dựng).

Để làm nền tảng, chúng tôi sử dụng Jenkins trên máy Mac, vì nó cũng chạy CI cho iOS của chúng tôi.

Trong khi tiếp cận vấn đề, tôi nghĩ rằng nếu ở cấp độ HĐH, thiết bị được tìm thấy, đó ít nhất là một sự khởi đầu. Thật vậy, chạy một lệnh như system_profiler SPUSBDataTypetìm thấy thành công thiết bị, bao gồm số sê-ri mà ADB báo cáo khi hoạt động chính xác.

Tôi đã thử một vài lệnh khá khập khiễng để "làm mới" tất cả hoạt động của USB, nhưng tôi không đi đâu cả. Không phải là bạn có thể gắn / ngắt kết nối thiết bị, nhưng thành thật mà nói tôi thậm chí không chắc vấn đề là ở đâu, tôi không biết đủ về các giao thức USB cấp thấp, chứ đừng nói đến máy Mac. Việc tôi giấu mã nguồn ADB là một cú đánh rất, rất dài.

Vì vậy, tại thời điểm này, tôi luôn chú ý đến một giải pháp cho phép chúng tôi chạy Android liên tục trên máy chủ CI của chúng tôi. Có thể là một vài lệnh trước mỗi công việc của Jenkins, vá ADB hoặc bất kỳ trò ảo thuật đen nào khác.

Câu trả lời:


9

Tìm thấy một cách để giải quyết nó, vì vậy đăng ở đây cho đầy đủ. Xin lưu ý rằng tôi không nói rằng đây là cách tốt nhất để giải quyết nó, nhưng nó hiệu quả với chúng tôi.

Vì vậy, chúng tôi nhận ra vấn đề xảy ra sau thời gian dài không hoạt động của CI (trong phạm vi giờ). Vì vậy, chúng tôi đã tạo ra một kịch bản đơn giản gọi adb devicescứ sau 10 giây. Và vấn đề không còn nữa, không còn vấn đề "chờ thiết bị" nữa.

Trên Linux, bạn có thể thực hiện việc này với một croncông việc đơn giản và trên OSX launchctlvà tôi chắc chắn có Windows tương đương.

Bất kể, "ping" các thiết bị cứ sau 10 giây đã giải quyết nó cho chúng tôi.


1
Cảm ơn! Có vẻ như tôi đã có cùng một vấn đề. Rút phích cắm và cắm lại cáp USB khiến thiết bị hiển thị trong danh sách.
Jorge Pedret

5

Kích hoạt gỡ lỗi USB (Cài đặt => Tùy chọn nhà phát triển) trong điện thoại.


1

Chúng tôi đã gặp một số vấn đề tương tự với môi trường Tích hợp liên tục với các thiết bị Android từ máy OSX (cũng sử dụng cho cả iOS và Android).

Tôi tin rằng vấn đề là bạn đang cho phép Jenkins khởi động máy chủ adb. Các nguyên nhân gây ra vấn đề bởi vì công việc Jenkins có liên quan đến vỏ sò đi vào và tồn tại. Nếu Jenkins khởi động daemon adb bằng một cuộc gọi "thiết bị adb" (ví dụ), thì daemon adb sẽ được sở hữu bởi một vỏ Jenkins tồn tại trong thời gian ngắn và khi lớp vỏ đó kết thúc thực thi và đóng lại, daemon adb sẽ được dọn sạch , cho đến khi nó được bắt đầu tự động sao lưu bằng một cuộc gọi adb khác. Điều này dẫn đến một chu kỳ bắt đầu và dừng daemon adb, nhưng những gì bạn muốn là nó sẽ duy trì vô thời hạn.

Một cách để khắc phục điều này là chỉ chạy "thiết bị adb" từ vỏ được mở trên máy CI. Bạn có thể biết đó có phải là tiến trình cha hay không bằng cách hiển thị thông báo này sau khi chạy

blah$ adb devices
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
List of devices attached
xxxxxxxxxxx          device

Đây là một bước khó chịu phải thực hiện mỗi khi máy của bạn khởi động lại và nếu có ai đóng cửa sổ lệnh đó, bạn sẽ trở lại vấn đề trước đó.

Về lý thuyết, một cách tốt hơn sẽ là tạo tệp .plist để kích hoạt trình nền adb khi khởi động. Dưới đây là một ví dụ: ~ / Library / LaunchAgents / server.adb.plist. Điều này về cơ bản chỉ chạy adb start-server từ trình khởi chạy người dùng để tránh Jenkins sở hữu nó.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>server.adb</string>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <false/>
    <key>ProgramArguments</key>
    <array>
        <string>/Users/Shared/Jenkins/android-sdk/platform-tools/adb</string>
        <string>start-server</string>
    </array>
  </dict>
</plist>

Tuy nhiên, vấn đề với điều này là nó chỉ khởi động adb, nhưng nó không chặn, vì vậy bạn không thể sử dụng chức năng kiểm soát khởi chạy KeepAlive. Ngoài ra, nó dường như không hoạt động cho mục đích mong muốn. Nếu bất cứ ai biết cách chạy adb trong chế độ "daemon", vì vậy nó không quay trở lại, thì cơ chế launchctl này có thể được thiết lập để tự động khởi động lại nếu nó chết, do đó đảm bảo rằng Jenkins không bao giờ có quyền sở hữu. Ồ, bây giờ tôi sẽ chạy "thiết bị adb" trong cửa sổ shell và để nó mở.


1

Tôi đã giải quyết điều này bằng cách sử dụng một dải năng lượng có thể lập trình để khởi động lại các trung tâm usb trước mỗi lần chạy thử. Điều này đã làm tương tự như rút và cắm cáp usb trở lại.


Bạn có thể expalin hơn?
Dinesh


0

Tôi chỉ muốn theo dõi về gợi ý tuyệt vời của juan-delgado . Tôi đã tìm thấy trên MacOS High Sierra, chạy adbcứ sau 10 giây với watchlệnh cũng có hiệu quả như một cách giải quyết nhanh:

watch -n 10 adb -d devices

Điều này cho phép tôi vượt qua việc tạo một .plisttệp, nhưng nhược điểm rõ ràng là nó không phải là một giải pháp lâu dài. Các watchlệnh có sẵn trên các phiên bản trước của OSX, vì vậy nó phải được hiệu quả đó là tốt.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.