Android:过于频繁地发布搜索方法导致崩溃

时间:2015-07-01 00:02:15

标签: android

我有一个搜索栏,一个搜索按钮(因为我刚转换为使用onKeyPress并且还没有删除它)和一个TextView。

它运作良好,除了每个按键发出一个新的Search()调用,旧的调用不会停止运行。如果我键入太快或太长,应用程序崩溃。当onKeyPress()触发时,如何更好地管理我的线程或退出之前的Search()执行?

谢谢!

的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="corp.dtc.tel" >

<application
    android:allowBackup="true"
    android:icon="@mipmap/tel_ico"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".TEL_Main_Activity"
        android:label="@string/app_name"
        android:theme="@style/Theme.AppCompat.Light.DarkActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest>

MainActivity.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingTop="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:orientation="vertical">

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:paddingTop="10dp"
    android:paddingLeft="10dp"
    android:paddingRight="10dp" >

    <EditText
        android:id="@+id/search_box"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:hint="Enter Here"
        android:inputType="text"
        android:textSize="12sp"
        android:layout_marginLeft="5dp"
        android:layout_weight="1" />

    <Button
        android:id="@+id/search_button"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:text="Search..."
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:onClick="Search"/>

</LinearLayout>

<TextView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_marginLeft="5dp"
    android:layout_marginRight="5dp"
    android:hint="List of Numbers will be here"
    android:id="@+id/list_view"
    android:maxLines="50"
    android:scrollbars="vertical"
    android:freezesText="true" />

</LinearLayout>

MainActivity.java

package corp.dtc.tel;

import android.content.Intent;
import android.graphics.Typeface;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.text.method.ScrollingMovementMethod;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.io.IOException;


public class TEL_Main_Activity extends ActionBarActivity {
TextView textView;
EditText editText;
Button button;
Employee[] list;
Employee[] employees;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ActionBar actionBar = getSupportActionBar();
    actionBar.setLogo(R.mipmap.tel_ico);
    actionBar.setDisplayUseLogoEnabled(true);
    actionBar.setDisplayShowHomeEnabled(true);

    LoadArray la = new LoadArray();
        try {
            employees = la.LoadArray(this, R.raw.droid);
        } catch (IOException e) {}

    setContentView(R.layout.activity_tel_main);

    textView = (TextView) findViewById(R.id.list_view);
    textView.setHorizontallyScrolling(true);
    textView.setMovementMethod(new ScrollingMovementMethod());
    textView.setTypeface(Typeface.MONOSPACE);

    button = (Button) findViewById(R.id.search_button);

    editText = (EditText) findViewById(R.id.search_box);
    editText.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            Search(findViewById(R.id.layout));
        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });
}

@Override
public void onResume() {
    super.onResume();
    try {
        //check if any view exists on current view
        Button style = ((Button) findViewById(R.id.search_button));
    } catch (Exception e) {
        Intent i = new Intent();
        i.setClass(getApplicationContext(), TEL_Main_Activity.class);
        i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(i);
    }

}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_tel_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

public void UpdateTextView () {
    textView.setText(String.format("%-20s %10s %10s", list[0].name, list[0].number, list[0].support));
    for (int x = 1 ; x < list.length & list[x] != null ; x++) {
        textView.append("\n" +
        (String.format("%-20s %12s %10s", list[x].name, list[x].number, list[x].support)));
    }
}

public void Search(View view) {
    textView.setText(null);
    EditText line = (EditText) findViewById(R.id.search_box);
    String[] tokens = line.getText().toString().split(" ");
    if (tokens.length == 0)
    {
        //There was nothing in the search box.
    }

    else {
        list = new Employee[50];
        int listCtr = 0; //Keeps ctr for list[]

        for (int dbCtr = 0 ; dbCtr < 5000 ; dbCtr++) {
            System.out.println(dbCtr);

            if (listCtr == 50)
                break;

            if (employees[dbCtr] == null)
            {
                //Should have less than 50 listed items and finished searching.
                //Now it is okay to update the list view.
                UpdateTextView();
                break;
            }

            if (employees[dbCtr].contains(tokens))
            {
                list[listCtr] = employees[dbCtr];
                listCtr++;
            }
        }
    }
}
}

应用目的:搜索公司员工列表,显示结果。(必须显示少于51个结果)

1 个答案:

答案 0 :(得分:0)

我不认为&#34;其他搜索没有停止运行&#34;真的很好地描述了这里出了什么问题。我没有看到任何&#34;线程。&#34;我认为问题在于您尝试进行搜索&#34; on keyPress,&#34;因此&#34; 每个 keyPress。&#34;

更好的方式来考虑你在这里尝试做的事情:&#34;我想自动按下按钮&#39;一旦用户停止输入。&#34;

所以,基本上,当用户开始按键时,你将启动一个计时器(如果这样的计时器还没有运行)设置为熄灭,比如说,1/2秒。然后,在任何情况下,您都会设置一个标记为true,表示&#34;用户最近按了一个键。&#34;

当计时器熄灭时,它会检查此标志是否为true。如果是这样,它会将标志设置为false并重新安排计时器再次以1/2秒再次启动。否则,它会执行&#34;按下按钮&#34;过去,它会重置(单独)标志,表示计时器正在运行。

只要用户每1/2秒按下至少一个按键,定时器就会继续自行重新安排(并且,没有其他人会尝试启动定时器,因为他们可以看到定时器&#39; s运行)。但是,最终,计时器将看到按键已被按下的标志保持假半秒。当它按下按钮时,&#34;导致搜索发生。

对于彻底的解决方案,在执行搜索之后,计时器例程将检查&#34;键已被按下&#34;再次举起旗帜。如果它仍然 false,则用户确实已停止输入,并且现在是时候展示这些搜索结果了。否则,计时器例程应该重新开始重新安排。

最终,用户停止输入。计时器将运行搜索,并且在完成此操作后,将看到用户仍然没有输入更多内容。然后将显示结果(第一次)。