如何才能使这段Android代码重用?

时间:2015-04-17 16:28:51

标签: android android-activity dry

我需要在加载数据时在许多不同的活动中显示忙碌指示符。这不是一个难题,但我讨厌重复自己。基类不是一个选项,因为我并不总是扩展相同的基本活动。

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

4 个答案:

答案 0 :(得分:3)

以上给出的答案非常明确和正确。 但是如果您不想将所有类扩展到BaseActivity,那么您可以选择其他方法。这是: -

  1. 创建一个类(Say MyApplication),它是类应用程序的子类。
  2. 现在在manifest中注册这个类,为了做到这一点,你只需要将name属性(android:name =" .MyApplication")提供给已经存在的应用程序标记。
  3. 编写用于在MyApplication类中显示和关闭ProgressDialog的代码。
  4. 它可以在您应用的任何活动中使用它。
  5. 这是代码片段。

    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(我们将使用showDialog和dismissDialog的活动。)

    ...
    ((MyApplication) getApplication()).showDialog("Hi", "This is message.");
    ((MyApplication) getApplication()).dismissDialog();
    ...
    

    在这里,您无需编辑您的活动签名。您只需创建它的Application类的SubClass。

    希望这有帮助!

    感谢。

答案 1 :(得分:1)

首先,将 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;
            }
        }
    }
 ...
}

现在你的其他活动就像,

public class MyActivity extends BaseActivity {
     ...
  getBusy()
  {
    .. getBusy() work done
  }
 ...
}

因为我假设您的正常活动中有getBusy()个方法。

第二次,将其放入任何Java类,并使用活动上下文和布尔参数生成updateProgressDialog(Context context, boolean flag)

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

现在从您的活动中调用它,

<Class_Object>.updateProgressDialog(this, getBusy()); //Here this refers to Activity reference

第三次,与第二次相同,但您必须将您的方法放在 Android应用程序类中,而不是普通Java类。所以不需要传递Context,只需要第二个布尔参数,就是它。

并称之为,(来自您的活动)  ((<Your_Application_Class>)getApplicationContext()).updateProgressDialog(getBusy());

答案 2 :(得分:0)

在公共静态类

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

另一个答案是更好的练习。

答案 3 :(得分:0)

这似乎是你的应用程序的设计问题:如果是主线程,长时间进程应该在后台线程中运行。 在main(在其他名称UI)线程中调用Activity的方法,如果你做了很长时间的过程,它会挂起UI。

如果您想通知用户您可以使用的长时间后台任务状态:

  • AsyncTask onProcessUpdate和onPostExecute方法向MainThread发送通知并显示processDialog
  • 使用某种事件总线从后台线程向ui线程发送通知消息

Asynctask示例:

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

}