我有问题。
我创建了一个带有一些按钮和GridView的Android页面。现在GridView充满了我网站上的json,我想每3秒重新加载GridView,而不会降低应用程序的速度!所以我尝试了这个:
在Page1加载无效中:
popChanger = (event) => {
this.setState( {userInput: event.target.value} );
console.log(event.target.value);
}
yourCity(){
return <div>
<input
type='text'
onChange={this.popChanger}
value={this.state.userInput}
/>
</div>
}
render() {
return (
<div className = "App">
{this.yourCity()}
</div>
);
}
}
函数:
RunOnUiThread(() => LoadOrdersAsync());
问题在于所有内容都已填满,但由于该线程的原因,UI滞后了。我该如何解决这个问题?
答案 0 :(得分:2)
您必须在不中断ui的情况下刷新网格视图,因为刷新网格视图必须在ui线程上完成。
如果应用太慢,那么您想立即用太多数据填充网格视图,因此需要花费一些时间来呈现所有行。
为您提供的解决方案是准备一些分页机制,我的意思是,仅加载可见的数据量+更多内容,并且当用户尝试向下滚动并且他尝试滚动超过可用行的内容时,再向您的行中添加另一行gridview,并在用户向下滚动时反复进行。
我过去有一个常见的问题,我正在编写xamarin表单应用程序,并且我有10万条记录的列表。如果您一次加载所有内容,您将挂起几秒钟,所以我想出了分页功能,并在需要时添加了更多内容,这真的很棒。
您可以为用户体验添加一些忙碌指示器。
编辑1:
首先,正如其他人已经提到的那样,您只需要使用ui线程来更新控件中的数据。我提到过分页机制(但是您还没有说出期望的行数),但是首先检查下面的代码是否仍然有问题,然后需要进行分页。您可以尝试仅用20个元素来更新列表,以测试列表是否有帮助。
//page1 load
private void Load()
{
LoadOrdersAsync();
}
private async Task LoadOrdersAsync()
{
while (true)
{
//Creating SortedList
var SortedOrderList = //add your logic
RunOnUiThread( ()=>
{
if (OrderListAdapter == null)
{
//Fill the DataSource of the ListView with the Array of Names
OrderListAdapter = new OrderListAdapter(this, SortedOrderList);
GridviewOrders.Adapter = OrderListAdapter;
}
else
{
OrderListAdapter.refresh(SortedOrderList);
}
});
// don't run again for at least 3 seconds
await Task.Delay(3000);
}
}
答案 1 :(得分:0)
编辑:添加了两个TODO
注释,这些注释应该在线程启动和停止时打印消息。不要使用断点,它们在调试后将无济于事。如果要获得稳定的用户体验,确实需要输出错误条件。
这可能有助于输出string message
:
Toast.MakeText(ApplicationContext, message, ToastLength.Long).Show();
我无法回答您的问题,但是我可以尝试使您步入正轨。
按以下步骤注释或减少代码至最低限度:
public async Task LoadOrdersAsync()
{
// TODO: print "thread started"
while (true)
{
// TODO: print "RUN!"
await Task.Delay(3000);
}
// TODO: print "thread stopped"
}
将TODO注释替换为实际的文本输出,例如 flash / toast 消息。
一旦确定运行正常,实际问题就出在有效载荷上。当在辅助线程中引发异常时,它们被抑制,该线程被杀死,但是没有立即输出。
将代码封装在try..catch
子句中,并像以前一样输出异常消息。为了提高可用性,请将错误输出保留在适当的位置。您至少要告诉您的应用程序的未来用户,后台出现了某些问题。这就是为什么您应该将工作错误输出保持在适当位置的原因。
这是代码支架:
public async Task LoadOrdersAsync()
{
// TODO: print "thread started"
while (true)
{
try
{
// TODO: all your actual payload code goes here
} catch (Exception ex)
{
// TODO: print ex.Message;
break; // you may or may not want to break the loop at this point
}
await Task.Delay(3000);
}
// TODO: print "thread stopped"
}
希望这对您有所帮助!
答案 2 :(得分:0)
通常,您应该将RunOnUiThread
中的操作最小化到最低限度。这意味着不应执行任何计算,而应执行与UI相关的工作。
因此,您应该执行以下操作:
var timer = new System.Threading.Timer(
{
//Do any work that is not UI related
RunOnUiThread(() => LoadOrders());
}, null, 0, 3000);
函数将是:
public void LoadOrders()
{
if (OrderListAdapter == null)
{
//Fill the DataSource of the ListView with the Array of Names
OrderListAdapter = new OrderListAdapter(this, SortedOrderList);
GridviewOrders.Adapter = OrderListAdapter;
}
else
{
OrderListAdapter.refresh(SortedOrderList);
}
}