У меня есть программа на Java, которую я только что превратил в Android-приложение, которое медленно загружается. Проблема: он имеет дело со «словарем» из 140 000 слов (хранящимся в файле Asset
), в котором нужно искать слова, соответствующие шаблонам «подстановочных знаков Windows»: например, S???CK* будет соответствовать STICKS, SHACK, STACK, , STACKOVERFLOW и т. д. Это ОЧЕНЬ быстро в Windows 7. Не так на телефоне.
Одна вещь, которую я сделал, это прочитал все 140 000 слов в ArrayList
(я был шокирован тем, что он скомпилировался и запустился), после чего, если шаблон не начинается с подстановочного знака, Collections.binarySearch(...)
делает поиск практически немедленным.
Но чтение его в список массивов занимает 60 секунд, а пользовательский ввод блокируется. И это происходит каждый раз, когда нужно запускать onCreate
, т. е. неприемлемо часто.
Я хочу ускорить это.
Вот SSCCE
того, что работает отлично, но слишком медленно:
MainActivity.java
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentTransaction
ft;
ft = getFragmentManager().beginTransaction();
ft.replace(R.id.layout_container, new OutputFragment());
ft.commit();
};
}
OutputFragment.java
public class OutputFragment extends Fragment
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater _layoutInflater,
ViewGroup _sourceOfLayoutParams,
Bundle savedInstanceState)
{
View v = _layoutInflater.inflate(R.layout.fragment_output,_sourceOfLayoutParams, false);
EditText et = (EditText)v.findViewById(R.id.txaOutput);
Matcher matcher = new Matcher(getActivity().getAssets());
for (int i = 0; i < 9; i++)
et.append("\n" + matcher.get(i));
return v;
}
}
Matcher.java
public class Matcher extends ArrayList<String> {
Matcher(AssetManager assets) {
Scanner scDict = null;
try { scDict = new Scanner(assets.open("dictionary.dic")); }
catch (IOException e) { e.printStackTrace(); }
int k = 0;
while(scDict.hasNext())// && ++k<10)
add(scDict.next());
}
}
activity_main.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width ="match_parent"
android:layout_height ="match_parent"
xmlns:tools ="http://schemas.android.com/tools"
tools:context =".MainActivity"
>
<LinearLayout
android:id ="@+id/layout_container"
android:orientation ="vertical"
android:layout_width ="match_parent"
android:layout_height="match_parent">
</LinearLayout>
</RelativeLayout>
fragment_output.xml
<GridLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width ="match_parent"
android:layout_height="match_parent"
android:rowCount="33"
android:columnCount="2">
<TextView
android:id ="@+id/txvOutput"
android:text ="Output shown below"
android:layout_width ="wrap_content"
android:layout_height ="wrap_content"
android:textAppearance ="?android:attr/textAppearanceLarge"
android:layout_row="0"
android:layout_column="0">
</TextView>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="@+id/txaOutput"
android:layout_row="2"
android:inputType="textMultiLine"
android:layout_column="0"
android:maxLines="100"/>
</GridLayout>
Так что я хочу, чтобы ускорить его. Я прочитал "Поддержание отклика приложения для Android". Я не знаю, смогу ли я сделать это в соответствии с моей ситуацией. Я взял пример оттуда и скорректировал его как мог:
private class LoadWords extends AsyncTask<Scanner, Integer, Long>
{
@Override
protected Long doInBackground(Scanner... params) { // variable arg list required (??)
while(params[0].hasNext()) //// no way this could work...
add(params[0].next());
return 0L;
};
}
Я не ожидал, что это сработает, как только я набрал params[0].hasNext()
, но, похоже, требуется список переменных аргументов.
Вот как я пытался это реализовать:
LoadWords loadWords = new LoadWords(); /////////////////////////
InputStream stream = null;
Scanner scDict = null;
...
stream = assets.open("dictionary.dic");
...
scDict = new Scanner(stream);
loadWords.execute(scDict); ///////////////////// What should I pass?????
Думаю, мне следует отказаться от этого подхода и попытаться использовать Thread
, которым мне придется управлять. Меня это не устраивает.
Любые предложения о том, как действовать, приветствуются.
AsyncTask
, но у меня есть мотивация. Я задам новый вопрос о том, как реализоватьAsyncTask
. - person DSlomer64   schedule 04.09.2015onCreate
? (2) Ускорит ли это доступ, если есть начальный подстановочный знак? Я считаю, что ведущий подстановочный знак обречен быть очень медленным. Поэтому мне нужно знать, какой выгоды ожидать, прежде чем я войду в эту новую область. - person DSlomer64   schedule 04.09.2015Cursor
в памяти иResultSet
вашего запроса. Кроме того, вы можете индексировать свое поле слова, и это ускорит работу. - person Paulo Avelar   schedule 04.09.2015