Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Одним из ключей поддержания адаптивного графического интерфейса является выполнение длительных задач в фоновом потоке, чтобы графический интерфейс не был заблокирован. Предположим, что мы хотим вычислить значение для отображения пользователю, но это значение занимает 5 секунд, чтобы вычислить:
public class ThreadDemo : Activity
{
TextView textview;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Create a new TextView and set it as our view
textview = new TextView (this);
textview.Text = "Working..";
SetContentView (textview);
SlowMethod ();
}
private void SlowMethod ()
{
Thread.Sleep (5000);
textview.Text = "Method Complete";
}
}
Это будет работать, но приложение будет "зависать" в течение 5 секунд во время вычисления значения. В это время приложение не будет реагировать на какое-либо взаимодействие с пользователем. Чтобы обойти это, мы хотим выполнить вычисления в фоновом потоке:
public class ThreadDemo : Activity
{
TextView textview;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Create a new TextView and set it as our view
textview = new TextView (this);
textview.Text = "Working..";
SetContentView (textview);
ThreadPool.QueueUserWorkItem (o => SlowMethod ());
}
private void SlowMethod ()
{
Thread.Sleep (5000);
textview.Text = "Method Complete";
}
}
Теперь мы вычисляем значение в фоновом потоке, чтобы наш графический интерфейс оставался адаптивным во время вычисления. Однако при выполнении вычисления приложение завершает работу, оставляя это в журнале:
E/mono (11207): EXCEPTION handling: Android.Util.AndroidRuntimeException: Exception of type 'Android.Util.AndroidRuntimeException' was thrown.
E/mono (11207):
E/mono (11207): Unhandled Exception: Android.Util.AndroidRuntimeException: Exception of type 'Android.Util.AndroidRuntimeException' was thrown.
E/mono (11207): at Android.Runtime.JNIEnv.CallVoidMethod (IntPtr jobject, IntPtr jmethod, Android.Runtime.JValue[] parms)
E/mono (11207): at Android.Widget.TextView.set_Text (IEnumerable`1 value)
E/mono (11207): at MonoDroidDebugging.Activity1.SlowMethod ()
Это связано с тем, что необходимо обновить графический интерфейс из потока графического интерфейса. Наш код обновляет графический интерфейс из потока ThreadPool, что приводит к сбою приложения. Нам нужно вычислить наше значение в фоновом потоке, но затем выполнить обновление в потоке ГРАФИЧЕСКОго интерфейса, который обрабатывается с помощью Activity.RunOnUIThread:
public class ThreadDemo : Activity
{
TextView textview;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Create a new TextView and set it as our view
textview = new TextView (this);
textview.Text = "Working..";
SetContentView (textview);
ThreadPool.QueueUserWorkItem (o => SlowMethod ());
}
private void SlowMethod ()
{
Thread.Sleep (5000);
RunOnUiThread (() => textview.Text = "Method Complete");
}
}
Этот код работает должным образом. Этот графический интерфейс остается адаптивным и правильно обновляется после выполнения вычисления.
Обратите внимание, что этот метод не просто используется для вычисления дорогого значения. Его можно использовать для любой длительной задачи, которая может выполняться в фоновом режиме, например вызов веб-службы или скачивание интернет-данных.