Android'de etkin olmayan InputConnection uyarısında getExtractedText uyarısı


129

Logcat'imde aşağıdaki uyarıyı alıyorum.

getExtractedText on inactive InputConnection

Bunun arkasındaki sebebi bulamıyorum. Lütfen yardım et


4
Bu soruda neyin belirsiz / belirsiz / eksik olduğunu anlamıyorum? Uygulamamı çalıştırırken logcat'imde bu uyarıyı alıyorum, bu uyarının nedenini bilmek istiyorum.
pankajagarwal

2
Bunu geliştirdiğim uygulamamda da görüyorum ve nereden geldiği veya neden olduğu hakkında hiçbir fikrim yok. Biri öğrenirse, lütfen bir yorum gönderin. Aslında "getExtractedText" dışında birçok farklı uyarı gösterir. Ayrıca şunu da görüyorum: "beginBatchEdit", "endBatchEdit", "getTextBeforeCursor" ve çok daha fazlası.
yayılma

1
bu soruya bakan moderatörler. Öyle değilse, yapmalılar çünkü bu sorunun 14 olumlu oylamadan sonra bile hala belirsiz ve anlamsız olduğuna inanıyorlarsa, o zaman ne diyeceğimi bilmiyorum
pankajagarwal

Aynı fikirdeyim, bu da ele almam gereken bir sorun. Nedeni hakkında hiçbir fikrim yok.
JonWillis

3
Bu hataya neden olan kodunuz nedir?
Bill the Lizard

Yanıtlar:


44

Benzer bir sorunla karşılaştım. Benim 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.

Durumum: Kullanıcının yazdığı bir EditText görünümüm var. EditText, kullanıcı bir düğmeye bastığında silinir. Düğmeye hızla bastığımda birçok etkin olmayan InputConnection girişi yayınlanıyor.

Ör:

editText.setText(null);

Yukarıdaki logcat'imdeki son satır, neler olduğuna dair harika bir gösterge sağlıyor. Yeterince elbette, InputConnection metni temizleme talepleriyle boğulmuş durumda. Silmeye çalışmadan önce metin uzunluğunu kontrol etmek için kodu değiştirmeyi denedim:

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

Bu, düğmeye hızlı bir şekilde basmanın artık IInputConnectionWrapper uyarılarının akışına neden olmaması nedeniyle sorunun azaltılmasına yardımcı olur. Bununla birlikte, kullanıcı bir şeyler yazmak ve düğmeye basmak arasında hızla geçiş yaptığında veya uygulama yeterli yük altındayken düğmeye bastığında, bu durum yine de sorunlara yol açabilir.

Neyse ki, metni temizlemenin başka bir yolunu buldum: Editable.clear () . Bununla hiç uyarı almıyorum:

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

Yalnızca metni değil (otomatik metin, otomatik karakter, multitap, geri alma) tüm giriş durumunu temizlemek istemeniz durumunda TextKeyListener.clear (Düzenlenebilir e) kullanabilirsiniz .

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

1
Ayrıca IInputConnectionWrapper uyarıları alıyordum ve uygulamam neredeyse ANR aldı, yöntem clear () benim için çalıştı ... setText ("") 'i ayarlamadan önce süper garip hata;
kutu

17

Güncelleme:

InputConnection uyarılarını almamın nedeni metni nerede ayarladığımdan değil (yani onTextChangedgeri aramada ya da the afterTextChanged) - kullanmamdan kaynaklanıyordu setText.

Arayarak sorunu aştım:

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

Not: Aramayı yine de afterTextChangedgeri aramada yapıyorum , ancak yine de uyarı olmadan çalışıyor ontextChanged.

Önceki cevap:

Senaryom biraz farklı olsa da logcat'te de aynı mesajları alıyordum. EditText'e gelen her karakteri (veya oluşturulan karakterleri / yapıştırılan metni) okumak ve ardından söz konusu EditText'i varsayılan bir başlatma dizesine sıfırlamak istedim.

Açık metin bölümü Johnson'ın yukarıdaki çözümüne göre çalışır. Ancak, metni sıfırlamak sorunluydu ve giriş bağlantı uyarıları alıyordum.

Başlangıçta onTextChanged(CharSequence s, ...)şu şekilde tanımlanmıştı:

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

Ne zaman onTextChanged(...)denir, EditText salt okunur modunda. Bunun getText.clear()onu çağırmaktan fazlasını yapamayacağımız anlamına mı geldiğinden emin değilim ( setText(...)çağrılar da inputConnection uyarıları üretir).

Ancak, geri arama afterTextChanged(Editable s), metni ayarlamak için doğru yerdir.

@Override
public void afterTextChanged(Editable s) {

    if (isResettingKeyboard)
        return;

    resetKeyboardString();

    // ... 
}

Bu, şimdiye kadar herhangi bir uyarı olmadan çalışıyor.


Ben de aynı sorunu yaşadım. Farkına vardığım şey, çözümünüz InputConnection uyarılarını ortadan kaldırsa da, afterTextChangedyöntemin hiddenKeyboardText.getText().clear();yanı sıra çağrıldığını hiddenKeyboardText.append("some string");ve bu gerçeğin de dikkate alınması gerektiğini fark ettim . Benden +1!
Nick

@ Nick gerçek - önemli sağlamak için if (isResettingKeyboard) return;... üstündedir
ahash

7

Yardım belgelerinden

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

InputConnection arabirimi, bir InputMethod'dan girişini alan uygulamaya geri giden iletişim kanalıdır. İmleç etrafındaki metni okumak, metin kutusuna metin kaydetmek ve uygulamaya ham anahtar olayları göndermek gibi şeyler yapmak için kullanılır.

Ek olarak, daha fazla okuma şovu

getExtractedText (): Bu yöntem, giriş bağlantısı geçersiz hale gelirse (işlemin çökmesi gibi) veya istemcinin metinle yanıt vermesi çok uzun sürerse ( dönmesi birkaç saniye verilir) başarısız olabilir . Her iki durumda da bir boş döndürülür.

Ayrıca bu tür metinlerdeki değişiklikleri ve uyarı değişikliklerini izliyor gibi görünüyor.

Sorunu araştırmak için, yaptığınız herhangi bir veritabanı sorgularını, belki de bir düzendeki liste görünümleri veya listeler etrafında araştırmanız gerekir.

Herhangi bir görüşünüz yoksa, örneğin arka planda rastgele oluyor, o zaman bunun bir UI öğesi sorunu olmadığını öneririm, bu yüzden metin alanlarını ve benzerlerini göz ardı edin. Bir imleçte bilgi depolayan veya bir imleç isteyen bir arka plan hizmeti olabilir.

Ayrıca, sorun uygulamanızdan mı kaynaklanıyor? veya belki de yakın zamanda yüklediğiniz bir başkası. Tam logCat izini listeleyin. Birisi sorunu tanıyabilir.

Bunun etrafına belirli bir şey yazmadıysanız, başkasının günlük mesajı veya belki de kullandığınız bir kütüphanenin günlük mesajı gibi bir tahminde bulunma tehlikesi var mı?


1
teşekkürler, db sorguları yapıyorum ama garip bir şekilde bu uyarı, uygulamayı emülatörde çalıştırırken görünmüyor, bu yüzden aslında cihazımda yüklü olan başka bir uygulamadan kaynaklanıyor olabilir. Bu yöne bakacak
pankajagarwal

Sanırım en son logCat, mesajlarınızı diğer uygulamalardan farklı olarak filtrelenmiş olarak gösteriyor. Yine de bunu doğrulayacak kadar yeterince kullanmadım. Yeni bir boş uygulama oluşturabilir ve uygulamanızı ortadan kaldıracak hatanın oluşup oluşmadığını görmek için günlük kedisini izleyebilirsiniz. sorun olmaktan.
Emile

@frieza mutlaka başka bir uygulama değildir. Sqlite ile ArrayAdapter ekledim ve şimdi telefonda da bu uyarıyı alıyorum. Sanırım emülatörde hata görmüyorsunuz çünkü yavaş olması ve sonuç olarak performans eşiklerinin devre dışı bırakılması.
alandarev

7

Ben de aynı sorunu yaşıyordum. Uyarı, yazılım klavyemden birinde etkinleştirildiğinde EditTextsve etkinlik odağı kaybettiğinde ortaya çıktı .

Yaptığım şey klavyeyi onPause () 'da gizlemekti;

@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
Cevap bu. Ekranda halihazırda yaptığınız aktiviteden uzaklaşmadan önce klavyeyi gizlediğinizden emin olun.
Gábor

1

Bu sorunu kendim için çözdüm belki de aynı sorunu yaşıyorsunuz.

Bu neden oldu Nesne içinde HeaderView arasında Liste Adaptörü .

Bir Görünümü şişirdim ve Nesneyi ilan ettim ve üzerine bir TextWatcher koydum .

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

Bunu eklendi Liste Adaptörü ve adaptör inşa ettiler.

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

Metin İzleyicinin çalıştığı her şey yolunda .

AMA , bağdaştırıcıyı ilk derlemeden sonra yeniden inşa edersem.

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

That HeaderView de yeniden oluşturuldu.

Bu uyarı, Nesne kaldırıldığı ve Metin İzleyici hala onu izlemeye ayarlandığı için gösterilecekti.

Liste Adaptör ve Nesne değiştirildi ve tahmin ediyorum Watcher Metin Olay olduğunda başka bir yol arıyordu.

Böylece uyarı söner ve mucizevi bir şekilde Metin İzleyici HeaderView ve Nesneyi bulur . Ancak odağı kaybeder ve bu uyarıyı kaydeder.

kullanma

JOBSadapter.notifyDataSetChanged();

sorunu çözdü.

AMA bir varsa NesneAdaptörü ve Metin İzleyici bağlı NesneAdaptörü . O zaman biraz daha çalışman gerekebilir.

Yaptığınız işi yaptıktan sonra Dinleyiciyi kaldırmayı ve tekrar eklemeyi deneyin.

Object.removeTextChangedListener();

veya

Object.addTextChangedListener(null);

1

Antoniom'un cevabının yanı sıra, yapılması gereken diğer işlemlerin gerçekten klavyeyi gizledikten sonra yapıldığından emin olun, bu nedenle klavyeyi aşağıdaki gibi gizlediyseniz:

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

, klavye gizlendikten sonra aşağıdaki gibi başarılı eylemleri gerçekleştirmiş olmanız gerekir:

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

0

EditText'ten metin değiştirmek veya almak zorunda olduğumda bu sorunu yaşadım ve odaklandı.

Bu yüzden değiştirmeden veya ondan almadan önce klavyeyi kapattım ve düzelttim.

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

Belki senin sorunun farklıdır.


0

Xml'ye şu şekilde bir girdi türü ekleyerek sorunumu çözdüm: android: inputType = "none | text | textCapWords | textUri"

ondan önce android: inputType = "text" Bu, sorunumu çözdü.


3
Benim için hiçbir şey yapmadı.
DSlomer64

0

Logcat'te hata: etkin olmayan InputConnection'da getTextBeforeCursor

Çözüm: Giriş Klavyenizi Gizleyin ve uygulamayı çalıştırın.


0

EditText'i temizlemeden önce yazılım klavyesini gizle - uyarılar gösterilmeyecektir.

Ayrıca, cihaza özel görünüyor . Bunu yalnızca Nexus 4'te (Android 7.1) gördüm. Emülatörler (8.0, 7.1) veya Nexus 5'te uyarı yok.


0

Benim sorunum görünürlüğünü ayarlayarak neden oldu EditTextiçin GONEve daha sonra hemen onu ayarıVISIBLE ben girişi metin değiştirildi ve bazı durumlarda görünüm gizli gereken her doğrulama koşuyordu gibi kullanıcı bir karakteri yazdınız her zaman.

Dolayısıyla çözüm, EditTextodağı kaybedebileceğinden Görünüm veya Düzenin görünürlüğünü UI veya durum güncellemeleri arasında GONE olarak ayarlamaktan kaçınmaktır.


0

aynı sorunu iface edin ve durum bilgisiz widget'ımı durumlu widget'a dönüştürerek düzeltmeyi deneyebilirsiniz

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.