如何使 Android 代码块可重用?
How can I make this block of Android code reusable?
我需要在加载数据时在许多不同的活动中显示忙指示器。这不是一个难题,但我讨厌重复自己。基础 class 不是一个选项,因为我并不总是扩展相同的基础 activity.
protected void updateProgressDialog() {
//we're going to keep the progress dialog around if anything's busy
if (getBusy()) {
if (mProgressDialog == null) {
mProgressDialog = new ProgressDialog(this, R.style.ProgressDialog);
mProgressDialog.show();
mProgressDialog.setContentView(R.layout.progress_layout);
}
} else {
if (mProgressDialog != null) {
mProgressDialog.dismiss();
mProgressDialog = null;
}
}
}
在public静态class
public static void updateProgressDialog(Context context, ProgressDialog mProgressDialog) {
//If you can't access getBusy(), you may want to use a boolean argument here
if (getBusy()) {
if (mProgressDialog == null) {
mProgressDialog = new ProgressDialog(context, R.style.ProgressDialog); //you might have to cast context, not sure
mProgressDialog.show();
mProgressDialog.setContentView(R.layout.progress_layout);
}
} else {
if (mProgressDialog != null) {
mProgressDialog.dismiss();
mProgressDialog = null;
}
}
}
另一个答案是更好的练习。
首先,做一个BaseActivity把updateProgressDialog()
方法放在里面。现在,用这个 BaseActivity.
扩展了你的 Activity
public class BaseActivity extends Activity {
...
ProgressDialog mProgressDialog ;
protected void updateProgressDialog() {
//we're going to keep the progress dialog around if anything's busy
if (getBusy()) {
if (mProgressDialog == null) {
mProgressDialog = new ProgressDialog(this, R.style.ProgressDialog);
mProgressDialog.show();
mProgressDialog.setContentView(R.layout.progress_layout);
}
} else {
if (mProgressDialog != null) {
mProgressDialog.dismiss();
mProgressDialog = null;
}
}
}
...
}
现在你的另一个Activity喜欢,
public class MyActivity extends BaseActivity {
...
getBusy()
{
.. getBusy() work done
}
...
}
因为我假设 getBusy()
方法在您的正常 activity 中可用。
Second,将其放入任何 Java class 并使 updateProgressDialog(Context context, boolean flag)
具有 activity 上下文和布尔参数
ProgressDialog mProgressDialog ;
public void updateProgressDialog(Context context, boolean flag) {
//we're going to keep the progress dialog around if anything's busy
if (flag) {
if (mProgressDialog == null) {
mProgressDialog = new ProgressDialog(context, R.style.ProgressDialog);
mProgressDialog.show();
mProgressDialog.setContentView(R.layout.progress_layout);
}
} else {
if (mProgressDialog != null) {
mProgressDialog.dismiss();
mProgressDialog = null;
}
}
}
现在从你的 activity 称呼它,
<Class_Object>.updateProgressDialog(this, getBusy()); //Here this refers to Activity reference
Third,它与 Second 相同,但不是 Normal Java Class 你必须将你的方法放在 Android 应用程序 Class 拥有它的上下文。所以不需要传递上下文,只传递第二个布尔参数,就是这样。
然后这样称呼它,(来自你的activity)
((<Your_Application_Class>)getApplicationContext()).updateProgressDialog(getBusy());
以上给出的答案非常清楚和正确。
但是,如果您不想将所有 classes 扩展到 BaseActivity,那么您可以 select 其他方法。在这里:-
- 创建一个 class(Say MyApplication),它将是 class Application 的 Subclass。
- 现在在清单中注册此 class,为此您只需将名称 属性(android:name=".MyApplication") 命名为已经存在的应用程序标签那里。
- 编写用于在 MyApplication 中显示和关闭 ProgressDialog 的代码 class。
- 就是这样,可以在您的应用程序的任何 activity 中使用它。
这是代码片段。
MyApplication.java
public class MyApplication extends Application {
static ProgressDialog progressDialog;
void showDialog(String title, String message) {
if (progressDialog == null) {
progressDialog = new ProgressDialog(getApplicationContext());
}
progressDialog.setTitle(title);
progressDialog.setMessage(message);
progressDialog.show();
}
void dismissDialog() {
progressDialog.dismiss();
}
}
清单文件(我们刚刚应用了名称 属性。)
<application android:name=".MyApplication"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SecondActivity"/>
MainActivity(Activity 我们将在其中使用 showDialog 和 dismissDialog。)
...
((MyApplication) getApplication()).showDialog("Hi", "This is message.");
((MyApplication) getApplication()).dismissDialog();
...
在这里您不需要编辑您的活动签名。您只需创建 SubClass of Application class 即可。
希望对您有所帮助!
谢谢。
这似乎是您的应用程序的设计问题:长时间的进程应该 运行 在后台线程而不是主线程。
Activity 的方法在主线程(其他名称 UI)中调用,如果您进行了长时间的处理,它会挂断 UI。
如果你想通知用户长时间的后台任务状态,你可以使用:
- AsyncTask onProcessUpdate 和 onPostExecute 方法向 MainThread 发送通知并显示 processDialog
- 使用某种事件总线将通知消息从后台线程发送到 ui 线程
异步任务示例:
public interface UserNotificationService {
void showProgressBar();
void hideProgressBar();
}
public class UserNotificationServiceImpl implements UserNotificationService {
private Context ctx;
private ProgressDialog mProgressDialog;
public UserNotificationServiceImpl(Context ctx) {
this.ctx = ctx;
}
@Override
public void showProgressBar() {
if(mProgressDialog == null) {
mProgressDialog = new ProgressDialog(ctx, R.style.ProgressDialog);
mProgressDialog.show();
mProgressDialog.setContentView(R.layout.progress_layout);
}
}
@Override
public void hideProgressBar() {
if(mProgressDialog!=null) {
mProgressDialog.dismiss();
mProgressDialog = null;
}
}
}
后台任务:
public class ExampleTask extends AsyncTask<Void, Void, Void> {
private UserNotificationService notificationService;
public ExampleTask(Context ctx) {
notificationService = new UserNotificationServiceImpl(ctx);
}
@Override
protected Void doInBackground(URL... urls) {
// ... do your long time work here ...
}
@Override
protected void onPreExecute () {
notificationService.showProgressBar();
}
@Override
protected void onPostExecute(Void result) {
notificationService.hideProgressBar();
}
}
我需要在加载数据时在许多不同的活动中显示忙指示器。这不是一个难题,但我讨厌重复自己。基础 class 不是一个选项,因为我并不总是扩展相同的基础 activity.
protected void updateProgressDialog() {
//we're going to keep the progress dialog around if anything's busy
if (getBusy()) {
if (mProgressDialog == null) {
mProgressDialog = new ProgressDialog(this, R.style.ProgressDialog);
mProgressDialog.show();
mProgressDialog.setContentView(R.layout.progress_layout);
}
} else {
if (mProgressDialog != null) {
mProgressDialog.dismiss();
mProgressDialog = null;
}
}
}
在public静态class
public static void updateProgressDialog(Context context, ProgressDialog mProgressDialog) {
//If you can't access getBusy(), you may want to use a boolean argument here
if (getBusy()) {
if (mProgressDialog == null) {
mProgressDialog = new ProgressDialog(context, R.style.ProgressDialog); //you might have to cast context, not sure
mProgressDialog.show();
mProgressDialog.setContentView(R.layout.progress_layout);
}
} else {
if (mProgressDialog != null) {
mProgressDialog.dismiss();
mProgressDialog = null;
}
}
}
另一个答案是更好的练习。
首先,做一个BaseActivity把updateProgressDialog()
方法放在里面。现在,用这个 BaseActivity.
public class BaseActivity extends Activity {
...
ProgressDialog mProgressDialog ;
protected void updateProgressDialog() {
//we're going to keep the progress dialog around if anything's busy
if (getBusy()) {
if (mProgressDialog == null) {
mProgressDialog = new ProgressDialog(this, R.style.ProgressDialog);
mProgressDialog.show();
mProgressDialog.setContentView(R.layout.progress_layout);
}
} else {
if (mProgressDialog != null) {
mProgressDialog.dismiss();
mProgressDialog = null;
}
}
}
...
}
现在你的另一个Activity喜欢,
public class MyActivity extends BaseActivity {
...
getBusy()
{
.. getBusy() work done
}
...
}
因为我假设 getBusy()
方法在您的正常 activity 中可用。
Second,将其放入任何 Java class 并使 updateProgressDialog(Context context, boolean flag)
具有 activity 上下文和布尔参数
ProgressDialog mProgressDialog ;
public void updateProgressDialog(Context context, boolean flag) {
//we're going to keep the progress dialog around if anything's busy
if (flag) {
if (mProgressDialog == null) {
mProgressDialog = new ProgressDialog(context, R.style.ProgressDialog);
mProgressDialog.show();
mProgressDialog.setContentView(R.layout.progress_layout);
}
} else {
if (mProgressDialog != null) {
mProgressDialog.dismiss();
mProgressDialog = null;
}
}
}
现在从你的 activity 称呼它,
<Class_Object>.updateProgressDialog(this, getBusy()); //Here this refers to Activity reference
Third,它与 Second 相同,但不是 Normal Java Class 你必须将你的方法放在 Android 应用程序 Class 拥有它的上下文。所以不需要传递上下文,只传递第二个布尔参数,就是这样。
然后这样称呼它,(来自你的activity)
((<Your_Application_Class>)getApplicationContext()).updateProgressDialog(getBusy());
以上给出的答案非常清楚和正确。 但是,如果您不想将所有 classes 扩展到 BaseActivity,那么您可以 select 其他方法。在这里:-
- 创建一个 class(Say MyApplication),它将是 class Application 的 Subclass。
- 现在在清单中注册此 class,为此您只需将名称 属性(android:name=".MyApplication") 命名为已经存在的应用程序标签那里。
- 编写用于在 MyApplication 中显示和关闭 ProgressDialog 的代码 class。
- 就是这样,可以在您的应用程序的任何 activity 中使用它。
这是代码片段。
MyApplication.java
public class MyApplication extends Application {
static ProgressDialog progressDialog;
void showDialog(String title, String message) {
if (progressDialog == null) {
progressDialog = new ProgressDialog(getApplicationContext());
}
progressDialog.setTitle(title);
progressDialog.setMessage(message);
progressDialog.show();
}
void dismissDialog() {
progressDialog.dismiss();
}
}
清单文件(我们刚刚应用了名称 属性。)
<application android:name=".MyApplication"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SecondActivity"/>
MainActivity(Activity 我们将在其中使用 showDialog 和 dismissDialog。)
...
((MyApplication) getApplication()).showDialog("Hi", "This is message.");
((MyApplication) getApplication()).dismissDialog();
...
在这里您不需要编辑您的活动签名。您只需创建 SubClass of Application class 即可。
希望对您有所帮助!
谢谢。
这似乎是您的应用程序的设计问题:长时间的进程应该 运行 在后台线程而不是主线程。 Activity 的方法在主线程(其他名称 UI)中调用,如果您进行了长时间的处理,它会挂断 UI。
如果你想通知用户长时间的后台任务状态,你可以使用:
- AsyncTask onProcessUpdate 和 onPostExecute 方法向 MainThread 发送通知并显示 processDialog
- 使用某种事件总线将通知消息从后台线程发送到 ui 线程
异步任务示例:
public interface UserNotificationService {
void showProgressBar();
void hideProgressBar();
}
public class UserNotificationServiceImpl implements UserNotificationService {
private Context ctx;
private ProgressDialog mProgressDialog;
public UserNotificationServiceImpl(Context ctx) {
this.ctx = ctx;
}
@Override
public void showProgressBar() {
if(mProgressDialog == null) {
mProgressDialog = new ProgressDialog(ctx, R.style.ProgressDialog);
mProgressDialog.show();
mProgressDialog.setContentView(R.layout.progress_layout);
}
}
@Override
public void hideProgressBar() {
if(mProgressDialog!=null) {
mProgressDialog.dismiss();
mProgressDialog = null;
}
}
}
后台任务:
public class ExampleTask extends AsyncTask<Void, Void, Void> {
private UserNotificationService notificationService;
public ExampleTask(Context ctx) {
notificationService = new UserNotificationServiceImpl(ctx);
}
@Override
protected Void doInBackground(URL... urls) {
// ... do your long time work here ...
}
@Override
protected void onPreExecute () {
notificationService.showProgressBar();
}
@Override
protected void onPostExecute(Void result) {
notificationService.hideProgressBar();
}
}