2014-03-26 38 views
0

在实现Thread/Handler/Looper意识形态以通过传递消息在后台处理信息时遇到一些响应问题。我真的不想使用AsyncTask类,因为我已经知道如何使用它来完成我正在尝试做的事情。使用Thread/Handler/Looper作为工作线程Android

有人能帮助我使用下面的代码使用GooglePlayServicesUtil类下载Apache许可证并将其显示在DialogFragment中的TextView中吗?

我最大的问题是,当我启动它时,它有时很快,但其他人显示DialogFragment速度很慢。也许我没有按照加载DialogFragment的最佳做法,我真的不知道。

更新 添加了现在正在运行的代码,但由于某种原因,我仍然在一段时间内得到了UI冻结。 有谁知道这是否是特定设备?我目前正在使用三星GS3。 。 。

我DialogFragment:

// Runs the Apache Source Code in the Background 
private void launchApacheDialogFragment(FragmentManager fm,FragmentTransaction ft) 
{ 
    counter++; 

    // Check if the Dialog Already Exists 
    m_dialogFragment = (ApacheLicenseDialog) fm.findFragmentByTag(APACHE_FRAGMENT); 

    if(m_dialogFragment != null) 
    { 
     ft.remove(m_dialogFragment); 
    } 
    ft.addToBackStack(APACHE_FRAGMENT); 

    m_dialogFragment = ApacheLicenseDialog.newInstance(counter); 

    m_dialogFragment.show(fm, APACHE_FRAGMENT); 

} 

最后我的case语句调用该方法:

// Case 3 = Show the Apache Open Source License information 
     case 3: 

      // Launch the DialogFragment 
      launchApacheDialogFragment(fm, ft); 

      // Break out of the Statement 
      break; 

public class ApacheLicenseDialog extends DialogFragment implements Handler.Callback{ 

// Message Constants 
private static final int MSG_DO_WORK  = 0; 
private static final int MSG_START   = 1; 
private static final int MSG_DONE   = 2; 
private static final int MSG_SHUTDOWN  = 3; 

// UI Elements 
private TextView m_textApacheLicense  = null; 
private Button m_btnOk      = null; 
private ProgressBar m_apacheProgress  = null; 

// Background Processing Objects 
private BackgroundThread m_bgThread   = null; 
protected Handler m_handler     = null; 

// Apache String Object 
private String apacheLicense    = null; 

// ---------------------------------------------------------------------------- 
// New Instance Method invokes DialogFragment constructor 

public static ApacheLicenseDialog newInstance(int counter) 
{ 
    // Create the Apache License Dialog 
    ApacheLicenseDialog dialog = new ApacheLicenseDialog(); 

    Bundle data = new Bundle(); 
    data.putInt("Counter", counter); 
    Log.d("COUNTER", "New Instance called: "+ Integer.toString(counter)+" times."); 

    // Set the Arguments for the Dialog 
    dialog.setArguments(data); 

    // Return the Dialog 
    return dialog; 
} 

// --------------------------------------------------------------------------- 
// Class Overrides 

/* (non-Javadoc) 
* @see android.support.v4.app.DialogFragment#onCreate(android.os.Bundle) 
*/ 
@Override public void onCreate(Bundle savedInstanceState) 
{ 
    // Perform the Default Behavior 
    super.onCreate(savedInstanceState); 
    setRetainInstance(true); 

    // Create a new Handler, Background thread, and Start the Thread 
    m_handler = new Handler(this); 
    m_bgThread = new BackgroundThread(); 
    m_bgThread.start(); 
} 

/* 
* (non-Javadoc) 
* 
* @see 
* android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater, 
* android.view.ViewGroup, android.os.Bundle) 
*/ 
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
{ 
    // Set the Layout from XML Resource 
    return inflater.inflate(R.layout.apache_dialog_fragment, null); 
} 

/* 
* (non-Javadoc) 
* 
* @see 
* android.support.v4.app.DialogFragment#onActivityCreated(android.os.Bundle 
*) 
*/ 
@Override public void onActivityCreated(Bundle savedInstanceState) 
{ 
    // Perform Default Behavior 
    super.onActivityCreated(savedInstanceState); 

    // Reference this Dialog and Set its Title 
    getDialog().setTitle(getActivity().getResources().getString(R.string.text_Apache_License_Title)); 


    // Reference the UI Elements 
    m_textApacheLicense = (TextView) getView().findViewById(R.id.textViewApacheLicense); 
    m_apacheProgress = (ProgressBar) getView().findViewById(R.id.apacheProgress); 
    m_btnOk    = (Button)  getView().findViewById(R.id.btnOkay); 

    // Add a Listener to the Button 
    m_btnOk.setOnClickListener(OkListener); 

    // Starts the Message Sending 
    init(); 

} 

/* (non-Javadoc) 
* @see android.support.v4.app.DialogFragment#onDismiss(android.content.DialogInterface) 
*/ 
@Override public void onDismiss(DialogInterface dialog) 
{ 
    // Cleaned up this code, and Added some logging to test my message passing 
      m_bgThread.m_workerHandler.obtainMessage(MSG_SHUTDOWN).sendToTarget(); 

    Log.d("DISMISSING", "Dismissed called on ApacheLicenseDialog"); 


    try { 
     m_bgThread.join(); 
     Log.d("JOINING_THREAD", "Attempting to join the Thread"); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    }finally{ 
     Log.d("JOINED_THREAD", "Thread successfully joined"); 
    } 

    // Perform the default behavior 
    super.onDismiss(dialog); 
} 

// ---------------------------------------------------------- 
// Handler.Callback Interface 

@Override public boolean handleMessage(Message msg) 
{ 
    switch(msg.what) 
    { 
    case MSG_START: 
     // Set the ProgressBar View to Visible 
     m_apacheProgress.setVisibility(View.VISIBLE); 
     break; 
    case MSG_DONE: 
     updateUI(msg); 
     break; 
    } 
    // return true 
    return true; 
} 

// --------------------------------------------------------------------------- 
// Private Class Method 

private void init() 
{ 
    // Send the Message to this Classes Handler 
    m_bgThread.m_workerHandler.obtainMessage(MSG_DO_WORK).sendToTarget(); 

} 

private void updateUI(Message msg) 
{ 
    // Set the ProgressBar View to Invisible 
    m_apacheProgress.setVisibility(View.INVISIBLE); 
    // Update the UI 
    m_textApacheLicense.setText(msg.obj.toString()); 
} 

private void obtainApacheLicense() 
{ 
    // Send message that the operation is Starting 
    m_bgThread.m_workerHandler.obtainMessage(MSG_START).sendToTarget(); 

    // Fetch the ApacheLicense 
    apacheLicense = GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo(getActivity()); 

    // Send Message the the operation is Done 
    m_handler.obtainMessage(MSG_DONE, apacheLicense).sendToTarget(); 
} 

// --------------------------------------------------------------------------- 
// Listeners 

private OnClickListener OkListener = new OnClickListener() 
{ 
    @Override public void onClick(View v) 
    { 
     // Dismiss the Dialog 
     dismiss(); 

    } 

}; 

// --------------------------------------------------------------------------- 
// BackgroundThread Class used to Fetch the Apache License from GooglePlayServicesUtil Class 

private class BackgroundThread extends Thread implements Handler.Callback{ 

    // Looper and Handler for the Background Thread 
    private Looper  m_workerLooper; 
    protected Handler m_workerHandler; 

    @Override public void run() 
    { 
     // Do background Processing 
     Looper.prepare(); 
     m_workerLooper = Looper.myLooper(); 
     m_workerHandler = new Handler(m_workerLooper, BackgroundThread.this); 
     Looper.loop(); 
    } 

    @Override public boolean handleMessage(Message msg) 
    { 
     switch(msg.what) 
     { 
     case MSG_DO_WORK: 
      // Run the obtainApacheLicenseFunction in this Thread 
      obtainApacheLicense(); 
      break; 
     case MSG_SHUTDOWN: 
      // Clean up the Looper by calling quit() on it 
      m_workerLooper.quit(); 
      Log.d("BACKGROUND_THREAD","Looper is shut down"); 
      break; 
     } 
     // Return true 
     return true; 
    } 

} 
} 

而且我用switch语句,例如显示此任何帮助,将不胜感激,这是一种令人讨厌的冻结拖延经验,虽然它的只是为了阅读开源许可证。

再次请帮助我使用Thread/Handler/Looper思想。我试图理解这个概念,而不是仅仅使用AsyncTask。

更新

我发现这个使用调试的角度来工作。我的线程启动并且我的处理程序处理所有消息,并且在我的对话框片段的生命周期结束时后台线程成功加入。我忘记了需要清理的东西吗?

感谢

+0

我想我的问题在于我使用,以显示该对话框的父活动。 。 。如果已经调用解雇,我该如何完全清理片段?还是我在做我需要做的一切? –

回答