Android 从异步任务更新片段

Android 从异步任务更新片段,android,android-fragments,Android,Android Fragments,一点背景: “onResume”连接到我的服务器询问信息时我的主要活动。这是正确的。 当活动收到应答时,它将数据加载到数组中,加载完数组后,它将调用位于主活动上的“UpdateFragments”。 这是 public void updateFragments() { List<Fragment> allFragments = getSupportFragmentManager().getFragments(); if (allFragments == null ||

一点背景: “onResume”连接到我的服务器询问信息时我的主要活动。这是正确的。 当活动收到应答时,它将数据加载到数组中,加载完数组后,它将调用位于主活动上的“UpdateFragments”。 这是

public void updateFragments() {
    List<Fragment> allFragments = getSupportFragmentManager().getFragments();
    if (allFragments == null || allFragments.isEmpty())
        return;
    for (Fragment fragment : allFragments)
        if (fragment.isVisible())
            ((UpdatableFragment) fragment).updateView();
}
现在让我们来看看这个奇怪的部分。。。对于以下代码(我们现在在片段中),它只起作用,当运行时,我有带字符串的空白片段:

private TextView tv;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.device_fragment, parent, false);
    tv = (TextView) view.findViewById(R.id.room);
    tv.setText("PRINT THIS");
    return view;
}
如果我将相同的代码放在updateView()过程中,并在onCreateView中调用它,它也可以工作:

@Override
public void updateView() {
    tv.setText("PRINT THIS");
}
但是。。。在这里我们有一个大的毛茸茸的但是。。。如果在异步任务按应有方式结束时从MainActivity调用updateView。。。文本从不打印。 而这种奇怪只是开始。。。如果我尝试调试代码。。当我到达tv.setText指令时,应用程序就死掉了。。。没有任何错误

02-07 16:48:18.015 1649-3024/? I/ActivityManager: Force stopping XXX appid=10185 user=0: from pid 23193
02-07 16:48:18.015 1649-3024/? I/ActivityManager: Killing 22729:XXX/u0a185 (adj 0): stop XXX
02-07 16:48:18.027 1649-3440/? I/WindowState: WIN DEATH: Window{8db1796 u0 XXX/XXX.MainActivity}
编辑: @恩博克曼可能是对的?这是主要的活动:

@Override
public void onStart() {
    super.onStart();
    mDataManager = new DataManager(this);
}
DataManager类是这样的: 建造商:

 public DataManager(MainActivity context) {
    super(context);
    mHandle = context;
    ... 
 }
异步任务调用以下命令:

public void onNewData(JSONObject data) {
    ...
    mHandle.updateFragments();
}

尝试在片段代码中创建一个方法,与前面的方法类似:

@Override
public void updateView() {
    tv.setText("PRINT THIS");
}
并从AsyncTask的“onPostExecute”调用它,如下所示:

protected void onPostExecute() {
    //Example of some fragment
    Yourfragment frag = ((Yourfragment) getSupportFragmentManager().findFragmentByTag("Yourfragment"));
    ((Yourfragment)frag).updateView();
 }

试试看

尝试在片段代码中创建一个方法,就像前面的方法一样:

@Override
public void updateView() {
    tv.setText("PRINT THIS");
}
并从AsyncTask的“onPostExecute”调用它,如下所示:

protected void onPostExecute() {
    //Example of some fragment
    Yourfragment frag = ((Yourfragment) getSupportFragmentManager().findFragmentByTag("Yourfragment"));
    ((Yourfragment)frag).updateView();
 }

试试看

您需要从UI线程调用
mHandle.updateFragments()
。由于您已经将
MainActivity
实例传递给DataManager的构造函数,因此只需执行此操作即可在UI线程上运行代码:

public void onNewData(JSONObject data) {
    mHandle.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            mHandle.updateFragments();
        }
    }
}
编辑:您可能还希望选择将
updateFragments
代码实际包装到runOnUiThread块中:

public void updateFragments() {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            List<Fragment> allFragments = getSupportFragmentManager().getFragments();
            if (allFragments == null || allFragments.isEmpty())
                return;
            for (Fragment fragment : allFragments) {
                if (fragment.isVisible())
                    ((UpdatableFragment) fragment).updateView();
            }
        }
    });
}
public void updateFragments(){
runOnUiThread(新的Runnable(){
@凌驾
公开募捐{
列出所有片段=getSupportFragmentManager().getFragments();
if(allFragments==null | | allFragments.isEmpty())
返回;
for(片段片段:所有片段){
if(fragment.isVisible())
((UpdateBlogment)fragment.updateView();
}
}
});
}

您需要从UI线程调用
mHandle.updateFragments()
。由于您已经将
MainActivity
实例传递给DataManager的构造函数,因此只需执行此操作即可在UI线程上运行代码:

public void onNewData(JSONObject data) {
    mHandle.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            mHandle.updateFragments();
        }
    }
}
编辑:您可能还希望选择将
updateFragments
代码实际包装到runOnUiThread块中:

public void updateFragments() {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            List<Fragment> allFragments = getSupportFragmentManager().getFragments();
            if (allFragments == null || allFragments.isEmpty())
                return;
            for (Fragment fragment : allFragments) {
                if (fragment.isVisible())
                    ((UpdatableFragment) fragment).updateView();
            }
        }
    });
}
public void updateFragments(){
runOnUiThread(新的Runnable(){
@凌驾
公开募捐{
列出所有片段=getSupportFragmentManager().getFragments();
if(allFragments==null | | allFragments.isEmpty())
返回;
for(片段片段:所有片段){
if(fragment.isVisible())
((UpdateBlogment)fragment.updateView();
}
}
});
}

不确定这是否是问题的原因,但您仍然可以从非UI线程调用
updateView
方法。您如何调用
updateFragments
方法?你能把它添加到你的帖子里吗?我曾经在片段itslef上使用过一种方法来更新他的观点。该活动应附加您想要的片段,但不附加其他内容。datamanager是否使用后台线程?您添加的代码片段没有帮助-除非初始化datamanager启动对服务器的数据请求并调用
updateFragments
方法。我想说的是:您正在某处调用
updateFragments
方法,只需在调用之前和之后显示几行。调用更新片段的上下文(或线程)非常重要-UI元素不能从非UI线程更新-尽管这会给您带来异常,而不仅仅是在没有消息的情况下崩溃,我还更新了datamanager部件不确定这是否是问题的原因,但您仍然可以从非UI线程调用
updateView
方法。您如何调用
updateFragments
方法?你能把它添加到你的帖子里吗?我曾经在片段itslef上使用过一种方法来更新他的观点。该活动应附加您想要的片段,但不附加其他内容。datamanager是否使用后台线程?您添加的代码片段没有帮助-除非初始化datamanager启动对服务器的数据请求并调用
updateFragments
方法。我想说的是:您正在某处调用
updateFragments
方法,只需在调用之前和之后显示几行。调用更新片段的上下文(或线程)非常重要-UI元素不能从非UI线程更新-尽管这会给您带来异常,而不仅仅是在没有消息的情况下崩溃,我还更新了datamanager部分您的
onPostExecute
中的代码肯定不起作用:您正在创建一个未附加到任何位置的片段的新实例。您的
onPostExecute
中的代码肯定不起作用:您正在创建一个未附加到任何位置的片段的新实例。