有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java将视图传递给AsyncTask以访问findViewById

我是Android编程新手,有一个问题

我正在尝试访问AsyncTask中的findViewById,但显然,默认情况下,这将不可用,因为我没有对视图对象执行任何操作

我发现了几篇文章,解释了如何解决这个问题,但它们都很老了,已经5年了,我想知道这是否仍然是正确的方法?我正在使用安卓的数据绑定方法,这应该取代findViewById调用,但我不知道如何在这种情况下

this方法解决问题仍然有效吗

这是我的代码,以防有更好的解决方案。我试图从AsyncTask中访问此视图中的progressbar

我的个人资料视图:

<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
    <variable name="user" type="Models.User" />
    <variable name="viewActions" type="ViewModel.ProfileViewModel" />
</data>

<LinearLayout xmlns:app="http://schemas.安卓.com/apk/res-auto"
    xmlns:tools="http://schemas.安卓.com/tools"
    xmlns:安卓="http://schemas.安卓.com/apk/res/安卓"
    安卓:layout_width="match_parent"
    安卓:layout_height="match_parent"
    安卓:orientation="vertical"
    安卓:gravity="center_horizontal|top">

    <ProgressBar
        安卓:id="@+id/progressPostUser"
        安卓:layout_width="120dp"
        安卓:layout_height="120dp"
        安卓:visibility="gone"/>

    <include layout="@layout/main_toolbar"/>

    <ImageView
        安卓:id="@+id/imagePlaceHolder"
        安卓:layout_width="250dp"
        安卓:layout_height="150dp"
        安卓:layout_marginTop="20dp"
        安卓:layout_marginBottom="5dp"
        安卓:src="@mipmap/ic_account"/>

    <LinearLayout
        安卓:layout_width="wrap_content"
        安卓:layout_height="wrap_content"
        安卓:layout_marginBottom="10dp">

        <ImageButton
            安卓:id="@+id/btnOpenCamera"
            安卓:layout_width="50dp"
            安卓:layout_height="50dp"
            安卓:layout_marginRight="10dp"
            安卓:src="@mipmap/ic_account"
            安卓:onClick="btnOpenCamper_OnClick"/>

        <ImageButton
            安卓:id="@+id/btnChooseImage"
            安卓:layout_width="50dp"
            安卓:layout_height="50dp"
            安卓:src="@mipmap/ic_view_list"/>

    </LinearLayout>

    <EditText
        安卓:layout_width="250dp"
        安卓:layout_height="50dp"
        安卓:hint="Name"
        安卓:text="@={user._name}"/>

    <EditText
        安卓:layout_width="250dp"
        安卓:layout_height="50dp"
        安卓:hint="Surname"
        安卓:text="@={user._surname}"/>

    <EditText
        安卓:layout_width="250dp"
        安卓:layout_height="50dp"
        安卓:hint="Email"
        安卓:text="@={user._email}"/>

    <Button
        安卓:layout_width="wrap_content"
        安卓:layout_height="wrap_content"
        安卓:text="Save"
        安卓:onClick="@{() -> viewActions.onSaveClicked(user)}"/>

</LinearLayout>

我的活动课:

public class ProfileActivity extends MenuActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ActivityProfileBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_profile);
    binding.setUser(new User());
    binding.setViewActions(new ProfileViewModel(this));

    //get the toolbar
    Toolbar tb = (Toolbar)findViewById(R.id.toolbarMain);
    setSupportActionBar(tb);
}
}

以及处理视图中事件的“视图模型”

public class ProfileViewModel {

private User mUser;
private Context mContext;

public ProfileViewModel(Context context){
    mContext = context;
}

public void onSaveClicked(User user) {
    String nameTest = user.get_name();
    String surnameTest = user.get_surname();

    Toast.makeText(mContext, user.get_name(), Toast.LENGTH_SHORT).show();
}
}

这是我的用户类

public class User extends BaseObservable {

public User() {

}

private String _name;
@Bindable
public String get_name() {
    return _name;
}
public void set_name(String _name) {
    this._name = _name;
    notifyPropertyChanged(BR._name);
}

private String _surname;
@Bindable
public String get_surname() {
    return _surname;
}
public void set_surname(String _surname) {

    this._surname = _surname;
    notifyPropertyChanged(BR._surname);
}

private String _email;
@Bindable
public String get_email() {
    return _email;
}
public void set_email(String _email) {

    this._email = _email;
    notifyPropertyChanged(BR._email);
}

private Bitmap _profileImage;
public Bitmap get_profileImage() {
    return _profileImage;
}
public void set_profileImage(Bitmap _profileImage) {
    this._profileImage = _profileImage;
}

public String toJsonString(){
    try{
        JSONObject jObject = new JSONObject();
        jObject.put("Name", get_name());
        jObject.put("Surname", get_surname());
        jObject.put("Email", get_email());
        jObject.put("ProfileImage", Base64.encodeToString(convertBitmapToBytes(), Base64.DEFAULT));
    } catch (Exception ex){
        Log.d("Error", "User.toJson");
    }
    return "";
}

@Override
public String toString() {
    return super.toString();
}

private byte[] convertBitmapToBytes(){
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    get_profileImage().compress(Bitmap.CompressFormat.PNG, 100, stream);
    return stream.toByteArray();
}

}


共 (1) 个答案

  1. # 1 楼答案

    我真的不喜欢将上下文和视图传递给不同的对象,并且喜欢将视图特定的功能保留在活动类本身中,所以我实现了一个接口,我传递了该接口,如下所示:

    这是我的界面:

    public interface IProfiler {
        void ShowProgressbar();
        void HideProgressbar();
        void MakeToast();
    }
    

    My activity类实现了这个接口,如下所示:

    public class ProfileActivity extends MenuActivity implements IProfiler {
    
    private ProgressBar mProgressar;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        ActivityProfileBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_profile);
        binding.setUser(new User());
        binding.setViewActions(new ProfileViewModel(this));
    
    
        //get the toolbar
        Toolbar tb = (Toolbar)findViewById(R.id.toolbarMain);
        setSupportActionBar(tb);
    
        //set the Progressbar
        mProgressar = (ProgressBar)findViewById(R.id.progressPostUser);
    }
    
    @Override
    public void ShowProgressbar() {
        mProgressar.setVisibility(View.VISIBLE);
    }
    
    @Override
    public void HideProgressbar() {
        mProgressar.setVisibility(View.GONE);
    }
    
    @Override
    public void MakeToast() {
        Toast.makeText(this, "Some toast", Toast.LENGTH_SHORT);
    }
    }
    

    My ProfileViewModel,除了作为参数的界面:

        public class ProfileViewModel {
    
        private User mUser;
        private IProfiler mProfiler;
    
        public ProfileViewModel(IProfiler profiler){
            mProfiler = profiler;
        }
    
        public void onSaveClicked(User user) {
            try {
                String nameTest = user.get_name();
                String surnameTest = user.get_surname();
    
                new AsyncTaskPost(mProfiler).execute(new URL("http://www.Trackme.com"));
            }
            catch (Exception ex) {
    
            }
        }
    }
    

    最后,我的帖子

    public class AsyncTaskPost extends AsyncTask<URL, Void, Void> {
    
    private IProfiler mProfilerActions;
    
    public AsyncTaskPost(IProfiler profilerActions){
        mProfilerActions = profilerActions;
    }
    
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        mProfilerActions.ShowProgressbar();
    }
    
    @Override
    protected Void doInBackground(URL... urls) {
        try{
            Thread.sleep(5000);
            return null;
        }
        catch (Exception ex) {
            return null;
        }
    }
    
    @Override
    protected void onPostExecute(Void aVoid) {
        mProfilerActions.HideProgressbar();
        mProfilerActions.MakeToast();
    }
    
    @Override
    protected void onCancelled() {
    
        super.onCancelled();
        mProfilerActions.HideProgressbar();
    }
    }