2016-09-09 2 views
-1

onCreateメソッドから開始して、内部にスレッドを持つフラグメントがあります。setRetainInstance(true)を使用したフラグメント内のスレッド

スレッドが終了した後、私は "clickButtonOperation"でアクティビティ(myActivity)にメッセージを送信する必要があります。

これは私のフラグメントののonCreate()メソッドです:NULLを返しonCreateView

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(); 
} 

私の質問は: 新しいアクティビティが添付された後、私の "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"); 
} 
} 

をこれら二つの作成:あなたがバックグラウンドスレッドからUIに触れることができない

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()); 
} 
} 

答えて

0

を..あなたはこのようなActivityクラスからrunOnUiThreadメソッドを使用する必要があります

@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(); 
} 
+0

私はあなたのソリューションが気に入っていますが、私の意図はUIに触れないようにしていますが、何かをするために主活動に通知するだけです。 –

+0

上記のsetRetainInstance(true)のコードは、メモリリークの問題を引き起こす可能性があります。あなたは、適切にmActivityを処理する必要があります。あなたはスレッドだけを使うことができますか? – masp

+0

はい、私はAsyncTaskでチェックアウトしますが、今ではスレッドで作業する必要があります... あなたは狂って行くことなくこれを使用するスマートな方法をお勧めしますか? –

関連する問題