简体   繁体   English

如何向片段发出异步任务尚未完成的信号

[英]How to signal to a fragment that an async task has not finished its task

In a fragment I want to prevent the user to start another task while the async task is not completed. 在一个片段中,我想防止用户在异步任务未完成时启动另一个任务。

So I have a global variable (counter) that I use to signal a value back to the fragment. 因此,我有一个全局变量(计数器),用于将值发信号给片段。 The async task starts and every second onProgressUpdate calls the method (setVal) to send the value of the counter to the fragment. 异步任务开始,并且每秒onProgressUpdate调用方法(setVal)将计数器的值发送到片段。 I receive the counter in the fragment. 我收到片段中的计数器。 It has the right value but each time I try to access it in the button btn1 its value is always 0. 它具有正确的值,但是每次我尝试在按钮btn1中访问它时,其值始终为0。

Why is that? 这是为什么? What is the right way to do what I want? 做我想要的正确方法是什么?

fragment: 分段:

public class Frag1 extends android.app.Fragment {
    private static TextView txt;
    private static View view;
    private int counter;

    public Frag1() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        view = null;
        view = inflater.inflate(R.layout.fragment_frag1, container, false);
        return view;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        txt = (TextView) getActivity().findViewById(R.id.txt);
        Button btn = (Button) getActivity().findViewById(R.id.btn1);
        btn.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Log.i("Frag1","val: "+counter);
                if(counter > 0) return;
                FragmentTransaction ft = getFragmentManager().beginTransaction();
                Frag2 f2 = new Frag2();
                ft.replace(R.id.content_frame, f2);
                ft.addToBackStack("f2");
                ft.commit();
            }
        });

        Button btn2 = (Button) getActivity().findViewById(R.id.btn2);
        btn2.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                AsyncCounter ac = new AsyncCounter(counter);
                ac.execute();
            }
        });

    }

    void setVal(int i){
        counter = i;
    }

}

Async task: 异步任务:

class AsyncCounter extends AsyncTask<Void, Integer, Void> {
    private int cnt;
    private  Frag1 f1 = new Frag1();

    public AsyncCounter(int counter) {
        cnt = counter;
    }

    @Override
    protected  Void doInBackground(Void... params) {
        for(int i=0;i<60;i++){
            publishProgress(i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        Log.i("ASYNC TASK","val: "+values[0]);
        cnt = values[0];
        f1.setVal(cnt);
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
    }

}

So you don't have a global variable. 因此,您没有全局变量。 You have an instance variable. 您有一个实例变量。 Instance variables are replicated for each object you create from the class where you declared those variables, so that each object can have its own state, separated and independently managed from the state of other objects of the same class. 实例变量是为您从声明了这些变量的类创建的每个对象复制的,因此每个对象可以具有自己的状态,并与同一类的其他对象的状态分开并进行独立管理。

It turns out you have many fragment objects. 事实证明您有许多片段对象。 One that is created by the system or by your activity code, showing its view on the screen. 由系统或您的活动代码创建的一种,在屏幕上显示其视图。 And the many you create in the task class, one for each time the onProgressUpdate method is called. 以及您在任务类中创建的许多类,每次调用onProgressUpdate方法一次。

Remember the bit about the "separated and independently managed" state of the objects created from a single class? 还记得有关从单个类创建的对象的“分离且独立管理”状态的内容吗? You see it at work here: the original fragment, the one you see on the screen, always keeps its counter's original value, the value it started with. 您可以在这里看到它的工作:原始片段,即您在屏幕上看到的片段,始终保持其计数器的原始值,即其起始值。 The task updates the counter's value of the fragments it creates; 任务更新其创建的片段的计数器值; and each counter is incremented only one time, because the task creates a new fragment each time it wants to update the counter. 并且每个计数器仅增加一次,因为该任务每次要更新计数器时都会创建一个新的片段。

To do what you want, you need to pass to the task a reference to the original fragment, eg as argument in the task's constructor. 要执行您想要的操作,您需要将对原始片段的引用传递给任务,例如,作为任务构造函数中的参数。 Then, use that reference to update the counter in onProgressUpdate . 然后,使用该引用来更新onProgressUpdate的计数器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM