getExtractedText no aviso inativo de InputConnection no android

128

Recebo o seguinte aviso no meu logcat.

getExtractedText on inactive InputConnection

Não consigo encontrar a razão por trás disso. Por favor ajude

pankajagarwal
fonte
4
Não entendo o que é ambíguo / vago / incompleto nesta questão? Recebo esse aviso no meu logcat enquanto executo meu aplicativo. Quero saber o motivo desse aviso.
Pankajagarwal
2
Também estou vendo isso no meu aplicativo que estou desenvolvendo e não tenho ideia de onde ele vem ou por quê. Se alguém descobrir, por favor, poste um comentário. Na verdade, ele mostra muitos avisos diferentes, exceto "getExtractedText". Também vejo: "beginBatchEdit", "endBatchEdit", "getTextBeforeCursor" e muito mais.
span
1
Os moderadores estão de olho nessa pergunta. Se não, então eles deveriam porque se eles ainda acreditam esta questão como vagos e amibiguous mesmo depois de 14 upvotes então eu não sei o que dizer
pankajagarwal
Concordo, este é um problema que também preciso resolver. Não faço ideia da causa.
JonWillis
3
Qual código você está causando esse erro?
Bill o Lagarto

Respostas:

44

Encontrei um problema semelhante. Meu logcat:

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.

Minha situação: eu tenho uma visualização EditText na qual o usuário digita. O EditText é limpo quando o usuário pressiona um botão. Muitas entradas InputConnection inativas saem quando eu pressiono rapidamente o botão.

Ex:

editText.setText(null);

A última linha do meu logcat acima fornece uma ótima indicação do que está acontecendo. Com certeza, o InputConnection é sobrecarregado por solicitações para limpar o texto. Eu tentei modificar o código para verificar o tamanho do texto antes de tentar limpá-lo:

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

Isso ajuda a atenuar o problema, pois pressionar o botão rapidamente não causa mais o fluxo de avisos IInputConnectionWrapper. No entanto, isso ainda está sujeito a problemas quando o usuário alterna rapidamente entre digitar alguma coisa e pressionar o botão ou pressiona o botão quando o aplicativo está com carga suficiente, etc.

Felizmente, encontrei outra maneira de limpar o texto: Editable.clear () . Com isso, não recebo avisos:

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

Observe que, se desejar limpar todo o estado de entrada e não apenas o texto (autotexto, autocap, multitap, desfazer), você pode usar TextKeyListener.clear (Editável e) .

if (editText.length() > 0) {
    TextKeyListener.clear(editText.getText());
}
Johnson Wong
fonte
1
Eu estava recebendo avisos IInputConnectionWrapper também e meu aplicativo ficou quase ANR, o método clear () funcionou para mim ... bug super estranho, antes de definir setText ("");
caixa
17

Atualizar:

O motivo pelo qual eu estava recebendo avisos de InputConnection não era por onde eu estava definindo o texto (ou seja, no onTextChangedretorno de chamada ou no afterTextChanged) - era porque eu estava usando setText.

Eu resolvi o problema ligando para:

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

Nota: Eu ainda faço a chamada no afterTextChangedretorno de chamada, embora funcione sem avisos ontextChangedtambém.

Resposta anterior:

Eu também estava recebendo mensagens idênticas no logcat, embora meu cenário fosse um pouco diferente. Eu queria ler todos os caracteres inseridos no EditText (ou caracteres compostos / texto colado) e redefinir o EditText em questão para uma sequência de inicialização padrão.

A parte do texto não criptografado funciona conforme a solução de Johnson acima. No entanto, redefinir o texto era problemático e eu recebia avisos de conexão de entrada.

Inicialmente, meu onTextChanged(CharSequence s, ...)foi definido da seguinte maneira:

@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;
}

Quando onTextChanged(...)é chamado, o EditText está no modo somente leitura. Não tenho certeza se isso significa que não podemos fazer mais do que chamá getText.clear()-lo (as setText(...)chamadas também produzem avisos inputConnection).

No entanto, o retorno de chamada afterTextChanged(Editable s)é o lugar certo para definir o texto.

@Override
public void afterTextChanged(Editable s) {

    if (isResettingKeyboard)
        return;

    resetKeyboardString();

    // ... 
}

Até agora, isso está funcionando sem nenhum aviso.

ahash
fonte
Eu também tive o mesmo problema. O que eu percebi foi que, apesar de sua solução marcas desaparecem as advertências InputConnection, notei que afterTextChangedmétodo é chamado em hiddenKeyboardText.getText().clear();, bem como sobre hiddenKeyboardText.append("some string");, e esse fato também deve ser levado em conta. +1 de mim!
Nick
@ Nick verdade - importante garantir if (isResettingKeyboard) return;é em cima ...
ahash
7

Nos documentos de ajuda

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

A interface InputConnection é o canal de comunicação de um InputMethod para o aplicativo que está recebendo sua entrada. É usado para executar tarefas como ler texto ao redor do cursor, confirmar texto na caixa de texto e enviar eventos de chave bruta para o aplicativo.

Além disso, outras leituras mostram

getExtractedText (): esse método pode falhar se a conexão de entrada se tornar inválida (como o processo travar) ou se o cliente estiver demorando muito para responder com o texto (são necessários alguns segundos para retornar) . Nos dois casos, um nulo é retornado.

Parece também monitorar as alterações nesse texto e alertar as alterações.

Para caçar o problema, você terá que explorar quaisquer consultas ao banco de dados que estiver fazendo, talvez em torno de listViews ou listas em um layout.

Se você não tem nenhuma visualização, por exemplo, está acontecendo aleatoriamente em segundo plano, então eu sugeriria que não é um problema de elemento da interface do usuário, portanto, ignore os campos de texto e tal. Pode ser um serviço em segundo plano que está armazenando informações em um cursor ou solicitando um cursor.

Além disso, o problema surge no seu aplicativo? ou talvez alguém que você instalou recentemente. Liste o rastreamento completo do logCat. Alguém pode reconhecer o problema.

Eu arriscaria um palpite de que, se você não escreveu algo específico em torno disso, alguém manda uma mensagem de log ou talvez a biblioteca que você está usando?

Emile
fonte
1
obrigado, eu faço consultas de banco de dados, mas estranhamente esse aviso não aparece ao executar o aplicativo no emulador, portanto, pode ser devido a algum outro aplicativo instalado no meu dispositivo. Vou olhar para essa direção
pankajagarwal
Acho que o logCat mais recente mostra suas mensagens distintas de outros aplicativos filtrados. Ainda não o usei o suficiente para confirmar isso. Você pode criar um novo aplicativo vazio e assistir ao gato de log para ver se o erro ocorre, isso eliminaria o seu aplicativo. de ser o problema.
Emile
@ Frieza não necessariamente outro aplicativo. Eu adicionei o ArrayAdapter com o sqlite e agora estou recebendo esse aviso também por telefone. Eu acho que você não vê erros no emulador porque está sendo lento e os limites de desempenho estão sendo desativados como consequência.
alandarev
7

Eu estava tendo o mesmo problema. O aviso apareceu quando o teclado virtual foi ativado em um dos meus EditTextse a atividade perdeu o foco.

O que fiz foi ocultar o teclado em 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();
}
antoniom
fonte
2
Esta é a resposta certa. Esconda o teclado antes de se afastar da atividade que você tem atualmente na tela.
Gábor
1

Resolvido esse problema por conta própria, talvez você tenha o mesmo problema.

Isso foi causado por um objeto no HeaderView do adaptador de lista .

Inflei um modo de exibição e declarei o objeto e coloquei um TextWatcher nele.

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
        }
});

Adicionou-o ao adaptador de lista e criou o adaptador.

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

Está tudo bem, o Text Watcher funciona.

MAS, se alguma vez reconstruir o adaptador após a compilação inicial.

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

Esse HeaderView também é reconstruído.

Esse aviso seria exibido porque o Objeto foi removido e o Observador de Texto ainda estava definido vigiando-o.

O adaptador de lista e o objeto foram substituídos, e acho que o Text Watcher estava olhando para o outro lado quando isso aconteceu.

Portanto, o aviso dispara e, milagrosamente, o Text Watcher encontra o HeaderView e o Object . Mas perde o foco e registra esse aviso.

Usando

JOBSadapter.notifyDataSetChanged();

corrigiu o problema.

MAS se você tiver um Objeto dentro do Adaptador , e o Observador de Texto estiver anexado ao Objeto dentro do Adaptador . Talvez você precise fazer um pouco mais de trabalho.

Tente remover o Ouvinte e conecte-o novamente depois de fazer o trabalho que estiver fazendo.

Object.removeTextChangedListener();

ou

Object.addTextChangedListener(null);
Xjasz
fonte
1

Além da resposta do antoniom, certifique-se de que qualquer outra ação necessária seja realmente executada após ocultar o teclado; portanto, se você ocultou o teclado como o abaixo:

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

, é necessário executar as ações seguintes após ocultar o teclado, da seguinte forma:

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

Eu tive esse problema quando precisei modificar ou obter texto do EditText e ele foi focado.

Portanto, antes de modificar ou sair dele, fechei o teclado e o corrigi.

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

Talvez seu problema seja diferente.

Angelo Moroni
fonte
0

Eu havia resolvido meu problema ao inserir um tipo de entrada no xml assim: android: inputType = "none | text | textCapWords | textUri"

antes disso era android: inputType = "text" Isso resolveu meu problema.

Neemias Fernandes
fonte
3
Não fez nada por mim.
DSlomer64
0

Erro no Logcat: getTextBeforeCursor em InputConnection inativo

Solução: Oculte seu teclado de entrada e execute o aplicativo.

shyam
fonte
0

Oculte o teclado do software antes de limpar o EditText - os avisos não serão mostrados.

Além disso, parece ser específico do dispositivo . Vi isso apenas no Nexus 4 (Android 7.1). Nenhum aviso sobre emuladores (8.0, 7.1) ou Nexus 5.

Inoy
fonte
0

Meu problema foi causado pela configuração da visibilidade de EditTextpara GONEe, em seguida, configurando-o imediatamente paraVISIBLE sempre que o usuário digitou um caractere, pois eu estava executando a validação na entrada cada vez que o texto era alterado e, em alguns casos, a exibição precisava ser oculta.

Portanto, a solução é evitar definir a visibilidade do modo de exibição ou layout como GONE entre atualizações de interface do usuário ou estado, pois isso EditTextpode perder o foco.

A coisa
fonte
0

iface o mesmo problema e corrija-o, convertendo meu widget sem estado em um widget statefull, você pode experimentá-lo

Mohamed Adly
fonte