getExtractedText trong cảnh báo InputConnection không hoạt động trên Android


127

Tôi nhận được cảnh báo sau trong logcat của tôi.

getExtractedText on inactive InputConnection

Tôi không thể tìm thấy lý do đằng sau nó. Xin vui lòng giúp đỡ


4
Tôi không hiểu những gì mơ hồ / mơ hồ / không đầy đủ trong câu hỏi này? Tôi nhận được cảnh báo này trong logcat của mình trong khi chạy ứng dụng của mình, tôi muốn biết lý do cho cảnh báo này.
pankajagarwal

2
Tôi cũng đang nắm bắt điều này trong ứng dụng của mình rằng tôi đang phát triển và tôi không biết nó đến từ đâu hoặc tại sao. Nếu bất cứ ai phát hiện ra, xin vui lòng gửi bình luận. Nó thực sự cho thấy nhiều cảnh báo khác nhau sau đó là "getExtractedText". Tôi cũng thấy: "startedBatchEdit", "endBatchEdit", "getTextB BeforeCoder" và nhiều hơn nữa.
khoảng

1
là người điều hành có một cái nhìn vào câu hỏi này. Nếu không thì họ nên bởi vì nếu họ vẫn tin câu hỏi này là mơ hồ và vô nghĩa ngay cả sau 14 lần nâng cấp thì tôi không biết phải nói gì
pankajagarwal

Tôi đồng tình, đây là một vấn đề tôi cũng cần giải quyết. Tôi không có ý tưởng về nguyên nhân.
JonWillis

3
Mã nào bạn có gây ra lỗi này?
Bill Lizard

Câu trả lời:


44

Tôi gặp phải một vấn đề tương tự. Logcat của tôi:

W/IInputConnectionWrapper(21214): getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper(21214): getSelectedText on inactive InputConnection
W/IInputConnectionWrapper(21214): getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper(21214): getTextAfterCursor on inactive InputConnection
...
I/Choreographer(20010): Skipped 30 frames!  The application may be doing too much work on its main thread.

Tình huống của tôi: Tôi có một EditText xem các loại người dùng vào. EditText sẽ bị xóa khi người dùng nhấn nút. Rất nhiều mục InputConnection không hoạt động phát ra khi tôi nhấn nhanh nút.

Ví dụ:

editText.setText(null);

Dòng cuối cùng trong logcat của tôi ở trên cung cấp một dấu hiệu tuyệt vời về những gì đang xảy ra. Chắc chắn, InputConnection bị choáng ngợp bởi các yêu cầu xóa văn bản. Tôi đã thử sửa đổi mã để kiểm tra độ dài văn bản trước khi thử xóa nó:

if (editText.length() > 0) {
    editText.setText(null);
}

Điều này giúp giảm thiểu vấn đề trong đó việc nhấn nút nhanh chóng không còn gây ra luồng cảnh báo IInputConnectionWrapper. Tuy nhiên, điều này vẫn dễ xảy ra sự cố khi người dùng nhanh chóng thay đổi giữa việc gõ một cái gì đó và nhấn nút hoặc nhấn nút khi ứng dụng đã đủ tải, v.v.

May mắn thay, tôi đã tìm thấy một cách khác để xóa văn bản: Editable.clear () . Với điều này, tôi không nhận được cảnh báo nào cả:

if (editText.length() > 0) {
    editText.getText().clear();
}

Lưu ý rằng nếu bạn muốn xóa tất cả trạng thái nhập và không chỉ văn bản (autotext, autocap, multitap, undo), bạn có thể sử dụng TextKeyListener.clear (Có thể chỉnh sửa e) .

if (editText.length() > 0) {
    TextKeyListener.clear(editText.getText());
}

1
Tôi cũng nhận được cảnh báo IInputConnectionWrapper và ứng dụng của tôi gần như ANR, phương thức rõ ràng () hoạt động với tôi ... lỗi siêu lạ, trước khi tôi cài đặt setText ("");
hộp

17

Cập nhật:

Lý do tôi nhận được cảnh báo InputConnection không phải vì tôi đang đặt văn bản (nghĩa là trong cuộc onTextChangedgọi lại hoặc afterTextChanged) - đó là vì tôi đang sử dụng setText.

Tôi đã khắc phục vấn đề bằng cách gọi:

hiddenKeyboardText.getText().clear();
hiddenKeyboardText.append("some string");

Lưu ý: Tôi vẫn thực hiện cuộc gọi trong cuộc afterTextChangedgọi lại, mặc dù nó cũng hoạt động mà không có cảnh báo ontextChanged.

Câu trả lời trước:

Tôi cũng nhận được tin nhắn giống hệt nhau trong logcat, mặc dù kịch bản của tôi hơi khác. Tôi muốn đọc mọi ký tự đi vào EditText (hoặc các ký tự được soạn thảo / văn bản đã dán), sau đó đặt lại EditText trong câu hỏi thành chuỗi khởi tạo mặc định.

Phần văn bản rõ ràng hoạt động theo giải pháp của Johnson ở trên. Tuy nhiên, việc đặt lại văn bản là có vấn đề và tôi sẽ nhận được cảnh báo kết nối đầu vào.

Ban đầu, tôi onTextChanged(CharSequence s, ...)được định nghĩa như sau:

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    if (isResettingKeyboard)
        return;

    // ... do what needs to be done

    resetKeyboardString();

}

public void resetKeyboardString()
{
    isResettingKeyboard = true;

    hiddenKeyboardText.getText().clear();
    hiddenKeyboardText.setText(keyboardInitString);
    hiddenKeyboardText.setSelection(defaultKeyboardCursorLocation);

    isResettingKeyboard = false;
}

Khi onTextChanged(...)được gọi, EditText ở chế độ chỉ đọc. Tôi không chắc điều này có nghĩa là chúng ta không thể làm gì hơn là gọi getText.clear()nó ( setText(...)các cuộc gọi cũng tạo ra cảnh báo inputConnection).

Tuy nhiên, cuộc gọi lại afterTextChanged(Editable s)là nơi thích hợp để đặt văn bản.

@Override
public void afterTextChanged(Editable s) {

    if (isResettingKeyboard)
        return;

    resetKeyboardString();

    // ... 
}

Điều này, cho đến nay, làm việc mà không có bất kỳ cảnh báo.


Tôi cũng gặp vấn đề tương tự. Điều tôi nhận ra là mặc dù giải pháp của bạn làm biến mất các cảnh báo InputConnection, tôi nhận thấy rằng afterTextChangedphương thức này được gọi hiddenKeyboardText.getText().clear();cũng như trên hiddenKeyboardText.append("some string");và thực tế này cũng cần được tính đến. +1 từ tôi!
Nick

@Nick đúng - quan trọng để đảm bảo if (isResettingKeyboard) return;là hàng đầu ...
ahash

7

Từ các tài liệu trợ giúp

http://developer.android.com/reference/android/view/inputmethod/InputConnection.html

Giao diện InputConnection là kênh liên lạc từ InputMethod trở lại ứng dụng đang nhận đầu vào. Nó được sử dụng để thực hiện những việc như đọc văn bản xung quanh con trỏ, cam kết văn bản vào hộp văn bản và gửi các sự kiện quan trọng đến ứng dụng.

Ngoài ra, đọc thêm cho thấy

getExtractedText (): Phương thức này có thể thất bại nếu kết nối đầu vào trở nên không hợp lệ (chẳng hạn như quá trình bị sập) hoặc máy khách mất quá nhiều thời gian để phản hồi với văn bản (được đưa ra vài giây để quay lại) . Trong cả hai trường hợp, một null được trả lại.

Nó dường như cũng giám sát các thay đổi đối với văn bản đó và các thay đổi cảnh báo.

Để tìm ra vấn đề, bạn sẽ phải khám phá bất kỳ truy vấn cơ sở dữ liệu nào bạn đang thực hiện, có thể xung quanh listViews hoặc danh sách trong một bố cục.

Nếu bạn không có bất kỳ chế độ xem nào, ví dụ như nó xảy ra ngẫu nhiên trong nền, thì tôi sẽ đề xuất rằng đó không phải là vấn đề yếu tố UI, vì vậy hãy bỏ qua các trường văn bản và như vậy. Nó có thể là một dịch vụ nền lưu trữ thông tin trong một con trỏ hoặc yêu cầu một con trỏ.

Ngoài ra, vấn đề phát sinh từ ứng dụng của bạn? hoặc có lẽ người khác mà bạn đã cài đặt gần đây. Liệt kê các dấu vết logCat đầy đủ. Ai đó có thể nhận ra vấn đề.

Tôi sẽ mạo hiểm đoán rằng nếu bạn chưa viết một cái gì đó cụ thể xung quanh điều này thì ai đó sẽ gửi thông điệp nhật ký, hoặc có lẽ là thư viện mà bạn đang sử dụng?


1
cảm ơn, tôi thực hiện các truy vấn db nhưng kỳ lạ là cảnh báo này không hiển thị khi chạy ứng dụng trên trình giả lập, vì vậy nó thực sự có thể là do một số ứng dụng khác được cài đặt trên thiết bị của tôi. Sẽ nhìn vào hướng này
pankajagarwal

Tôi nghĩ rằng logCat mới nhất hiển thị cho bạn tin nhắn của bạn khác với các ứng dụng khác, được lọc. Chưa sử dụng nó đủ để xác nhận điều đó. Bạn có thể tạo một ứng dụng trống mới và xem con mèo đăng nhập để xem nếu xảy ra lỗi, điều đó sẽ loại bỏ ứng dụng của bạn. từ vấn đề
Emile

@frieza không nhất thiết phải là ứng dụng khác. Tôi đã thêm ArrayAd CHƯƠNG với sqlite và hiện tôi cũng nhận được cảnh báo này trên điện thoại. Tôi đoán bạn không thấy lỗi trên trình giả lập vì nó bị chậm và các ngưỡng hiệu suất bị vô hiệu hóa.
alandarev

7

Tôi đã có cùng một vấn đề. Cảnh báo xuất hiện khi bàn phím mềm được kích hoạt ở một trong EditTextsnhững hoạt động của tôi và mất tập trung.

Những gì tôi đã làm là ẩn bàn phím trong onPause ();

@Override
protected void onPause() {

    // hide the keyboard in order to avoid getTextBeforeCursor on inactive InputConnection
    InputMethodManager inputMethodManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);

    inputMethodManager.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);

    super.onPause();
}

2
Đây là câu trả lời đúng. Đảm bảo bạn ẩn bàn phím trước khi bạn rời khỏi hoạt động bạn hiện có trên màn hình.
Gábor

1

Giải quyết vấn đề này cho bản thân tôi có thể bạn có cùng một vấn đề.

Điều này được gây ra bởi một Đối tượng trong HeaderView của Danh sách bộ điều hợp .

Tôi đã thổi phồng View và khai báo Object và đặt TextWatcher lên nó.

View v = LayoutInflater.from(CONTEXT).inflate(R.layout.in_overscrollview, null);
Object= (Object) v.findViewById(R.id.OBJECT_ID);

Object.addTextChangedListener(new TextWatcher() {
        @Override
        public void afterTextChanged(Editable s) {
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after){
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
        //Do my work
        //Update my view
        }
});

Đã thêm nó vào Danh sách bộ điều hợp và xây dựng bộ chuyển đổi.

JobListView = (ListView) getListView().findViewWithTag("JOBLISTVIEWTAG");
JobListView.addHeaderView(v, null, false);
JobsAdapter = new IN_JOBS_ADAPTER(CONTEXT, ITEMS_FOR_ADATER);
ListView.setAdapter(JOBSadapter);

Mọi thứ đều ổn, Text Watcher hoạt động.

NHƯNG nếu tôi từng xây dựng lại bộ chuyển đổi sau khi xây dựng ban đầu.

JobsAdapter = new IN_JOBS_ADAPTER(CONTEXT, DIFFERENT_ITEMS_FOR_ADAPTER);
ListView.setAdapter(JOBSadapter);

HeaderView đó cũng được xây dựng lại.

Cảnh báo đó sẽ hiển thị vì Đối tượng đã bị xóa và Trình xem Văn bản vẫn được đặt để theo dõi.

Bộ điều hợp danh sáchđối tượng đã được thay thế và tôi đoán Trình xem văn bản đang nhìn theo hướng khác khi nó xảy ra.

Vì vậy, cảnh báo tắt và thật kỳ diệu, Trình theo dõi văn bản tìm thấy HeaderViewObject . Nhưng nó mất tập trung và ghi lại cảnh báo đó.

Sử dụng

JOBSadapter.notifyDataSetChanged();

đã khắc phục sự cố.

NHƯNG nếu bạn có một Đối tượng bên trong Bộ điều hợpTrình theo dõi văn bản được gắn vào Đối tượng bên trong Bộ điều hợp . Sau đó, bạn có thể cần phải làm thêm một chút công việc.

Hãy thử loại bỏ Trình nghe và đính kèm lại sau khi thực hiện bất kỳ công việc nào bạn có thể làm.

Object.removeTextChangedListener();

hoặc là

Object.addTextChangedListener(null);

1

Ngoài câu trả lời của antoniom, hãy đảm bảo rằng mọi hành động tiếp theo cần phải được thực hiện, thực sự được thực hiện sau khi ẩn bàn phím, vì vậy nếu bạn đã ẩn bàn phím như dưới đây:

public void hideKeyboard() {
InputMethodManager inputMethodManager =(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0);
}

, bạn cần phải thực hiện các hành động thành công được thực hiện khi ẩn bàn phím, như vậy:

getWindow().getDecorView().post(new Runnable() {            
        @Override
        public void run() {
            finish(); //Sample succeeding code
     }
});

0

Tôi gặp vấn đề này khi tôi phải sửa đổi hoặc lấy văn bản từ EditText và nó đã được tập trung.

Vì vậy, trước khi sửa đổi hoặc nhận được từ nó, tôi đã đóng bàn phím và tôi sửa nó.

InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);

Có thể, vấn đề của bạn là khác nhau.


0

Tôi đã giải quyết vấn đề của mình khi chèn một kiểu đầu vào trên xml như thế này: android: inputType = "none | text | textCapemme | textUri"

trước đó là android: inputType = "text" Điều này đã giải quyết vấn đề của tôi.


3
Không làm gì cho tôi.
DSlomer64

0

Lỗi trong Logcat: getTextB BeforeCoder trên InputConnection không hoạt động

Giải pháp: Ẩn Bàn phím nhập của bạn và chạy ứng dụng.


0

Ẩn bàn phím phần mềm trước khi xóa EditText - cảnh báo sẽ không được hiển thị.

Ngoài ra, nó có vẻ là thiết bị cụ thể . Tôi chỉ thấy nó trên Nexus 4 (Android 7.1). Không có cảnh báo nào về trình giả lập (8.0, 7.1) hoặc Nexus 5.


0

Vấn đề của tôi là do thiết lập khả năng hiển thị của EditTextđể GONEvà sau đó ngay lập tức thiết lập nó để VISIBLEmỗi khi người dùng gõ một nhân vật, như tôi đã chạy xác nhận vào đầu vào mỗi thời điểm văn bản thay đổi và trong một số trường hợp, các điểm cần thiết để được ẩn.

Do đó, giải pháp là tránh đặt chế độ hiển thị của Chế độ xem hoặc Bố cục thành Gone giữa các bản cập nhật giao diện người dùng hoặc trạng thái, vì EditTextcó thể mất tập trung


0

tìm ra vấn đề tương tự và khắc phục nó bằng cách chuyển đổi widget không trạng thái của tôi sang widget đầy đủ, bạn có thể thử nó

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.