在實現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。
更新
我發現這個使用調試的角度來工作。我的線程啓動並且我的處理程序處理所有消息,並且在我的對話框片段的生命週期結束時後臺線程成功加入。我忘記了需要清理的東西嗎?
感謝
我想我的問題在於我使用,以顯示該對話框的父活動。 。 。如果已經調用解僱,我該如何完全清理片段?還是我在做我需要做的一切? –