带有setRetainInstance的片段中的线程(true)

时间:2016-09-09 15:46:21

标签: android multithreading user-interface fragment

我有一个带有线程的片段,从onCreate方法开始。

线程完成后,我需要通过“clickButtonOperation”向活动(myActivity)发送消息。

这是我片段的onCreate()方法:

public class HolderFragment extends My_Fragment{

private Thread myThread;

.
.
.

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

    setRetainInstance(true);
    printf("MyActivity attached is: "+myActivity);

    myThread=new Thread(new Runnable(){


        @Override
        public void run() {

            int i=0;
            while (i<3){

                printf("Working...");
                try {

                    Thread.sleep(2000);
                }
                catch (InterruptedException e) {

                    e.printStackTrace();
                }
                i++;
            }

            myActivity.clickButtonOperation(new Object[]{

                    HolderFragment.this.toString()
            });
        }
    });

    myThread.start();
}

onCreateView返回NULL。

我的问题是: 是否保证在附加新活动后调用我的“clickButonOperation”?或者可以在此过程之前调用此方法吗?

临时解决方案:

我创建了一个自定义Thread类:

public abstract class My_Thread extends Thread {

private boolean runnable=true;
private boolean paused=false;
private Object[] arguments;
private My_ThreadHolder myHolder;

protected void onPostExecute(Object[] arguments){

    while(paused);
    runnable=false;
}

protected abstract void execute(Object[] arguments);

protected void notifyUpdate(){

    while (paused);
}

protected boolean isRunnable(){

    return runnable;
}

public void setArguments(Object[] arguments){

    this.arguments=arguments;
}

public Object[] getArguments() {

    return arguments;
}

public final void run(){

    while (runnable){

        execute(arguments);
        onPostExecute(arguments);
    }
}

public void attach(My_ThreadHolder holder){

    myHolder=holder;
}


public My_ThreadHolder getHolder() {

    return myHolder;
}

public void startThread(){

    runnable=true;
    start();
}

public void stopThread(){

    runnable=false;
}

public void pauseThread(){

    paused=true;
    printf("Thread paused");
}

public void resumeThread(){

    paused=false;
    printf("Thread resumed");
}
}

创造了这两个:

public class My_ThreadHolder extends My_Fragment{

private TestThread myThread;

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

    setRetainInstance(true);
    printf("MyActivity attached is: "+myActivity);
    myThread=new TestThread();
    myThread.attach(this);
    myThread.startThread();
}

@Override
public void onAttach(Context context) {
    super.onAttach(context);

    if (myThread!=null)myThread.resumeThread();
}

@Override
public void onDetach() {
    super.onDetach();

    myThread.pauseThread();
}

protected void onNotifyUpdateReceived(Object[] arguments){

    myActivity.clickButtonOperation(arguments);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {return null;}

@Override
protected void setGraphics(View view, Bundle savedInstanceState) {}
}

class TestThread extends My_Thread{


@Override
protected void onPostExecute(Object[] arguments) {
    super.onPostExecute(arguments);

    printf("Thread finished");
}

@Override
protected void execute(Object[] arguments) {

    int i=0;
    while(i<3){

        printf("Working...");

        try {

            Thread.sleep(2000);
        }
        catch (InterruptedException e) {

            e.printStackTrace();
        }
        i++;

        Object[] myArguments= new Object[2];
        myArguments[0]=0;
        myArguments[1]=i;
        setArguments(myArguments);
        notifyUpdate();
    }
}

@Override
protected void notifyUpdate() {

    super.notifyUpdate();

    getHolder().onNotifyUpdateReceived(getArguments());
}
}

1 个答案:

答案 0 :(得分:0)

您无法从后台线程触摸UI ..您需要使用runOnUiThread类中的Activity方法,类似这样的

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

    setRetainInstance(true);
    printf("MyActivity attached is: "+myActivity);

    myThread = new Thread(new Runnable() {
        @Override
        public void run() {
            int i = 0;
            while (i < 3) {
                printf("Working...");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                i++;
            }

            myActivity.runOnUiThread(new Runnable() {
                 @Override
                 public void run() {
                     myActivity.clickButtonOperation(new Object[]{
                         HolderFragment.this.toString()
                     });
                 }
            });
        }
    });

    myThread.start();
}