当前位置: 首页 > 知识库问答 >
问题:

如何让我的请求在后台运行,同时填充其他EditText(线程)?

费学
2023-03-14

我是线程新手,但我有一个EditText视图,每当它失去焦点时,它就会使用用户从EditText输入的图像徽标填充回收视图。但是,每当用户失去焦点并调用该方法时,一切都会停止一段时间(这意味着我不擅长线程)。如何改进此代码,使其能够顺利运行?

我的活动类:

public class addItem extends AppCompatActivity {

    LoadingDialog loadingDialog;
    RecyclerView imgList;
    ArrayList<Bitmap> bitmapList = new ArrayList<>();
    BitmapAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
       /*
       / Code Unnecessary to the problem…
       */
       et_title.setOnFocusChangeListener((v, hasFocus) -> {
            if(!hasFocus){
                getImageLogo(et_title.getText().toString());
            }
        });
    }

    @SuppressLint("NotifyDataSetChanged")
    private void getImageLogo(String serviceName){
        googleRequest googleList = new googleRequest(serviceName);
        googleList.start();
        try {
            googleList.join();
        } catch (InterruptedException e) {
            Log.e("Interrupted Error","Thread Was Interrupted unexpectedly",e);
        }
        if(googleList.getImgRealList() != null) {
            bitmapList.clear();
            bitmapList.addAll(googleList.getImgRealList());
        }else {
            bitmapList.clear();
        }
        adapter.notifyDataSetChanged();
    }

我的googleRequest类:

public class googleRequest extends Thread {

    private ArrayList<Bitmap> imgRealList;
    private final String keyword;

    public googleRequest(String keyword){
        this.keyword = keyword;
    }

    public ArrayList<Bitmap> getImgRealList() {
        return imgRealList;
    }

    @Override
    public void run() {
        String newKeyword = keyword.toLowerCase(Locale.ROOT);
        newKeyword = newKeyword.replace(' ','+');
        String url = "https://www.google.gr/search?bih=427&biw=1835&hl=el&gbv=1&tbm=isch&og=&ags=&q="+ newKeyword;
        try {
            Document document = Jsoup.connect(url).get();
            imgRealList = new ArrayList<>();
            Elements imgList = document.select("img");
            for (int i=1;i<imgList.size();i++) {
                if(i==8)
                    break;
                String imgSrc = imgList.get(i).absUrl("src");
                InputStream input = new java.net.URL(imgSrc).openStream();
                Bitmap bitmap = BitmapFactory.decodeStream(input);
                imgRealList.add(bitmap);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

共有1个答案

邓深
2023-03-14

这是一个如何使用回调实现它的示例,正如我在评论中提到的。为此,我们需要定义一个回调函数,我将其命名为下面的函数,为了方便起见,您可以更改名称。

它是一个简单的java接口。

/// Must be executed in the UI (main) thread.
@MainThread
public interface RequestConsumer {
    void onRequestResult(List<Bitmap> bitmaps);
}

googleRequest线程类。

public class googleRequest extends Thread {

    private ArrayList<Bitmap> imgRealList;
    private final String keyword;
    /*
    We will use the request consumer callback in order to deliver the results
    to the UI from background. Since we need to touch the UI by this callback
    we ensure that it will execute within the UI thread's queue using the
    uiHandler.
    */
    private final RequestConsumer requestConsumer;
    private final Handler uiHandler = new Handler(Looper.getMainLooper());

    public googleRequest(@NonNull String keyword, @NonNull RequestConsumer requestConsumer){
        this.keyword = keyword;
        this.requestConsumer = requestConsumer;
    }

    @Override
    public void run() {
        String newKeyword = keyword.toLowerCase(Locale.ROOT);
        newKeyword = newKeyword.replace(' ','+');
        String url = "https://www.google.gr/search?bih=427&biw=1835&hl=el&gbv=1&tbm=isch&og=&ags=&q="+ newKeyword;
        try {
            Document document = Jsoup.connect(url).get();
            imgRealList = new ArrayList<>();
            Elements imgList = document.select("img");
            for (int i=1;i<imgList.size();i++) {
                if(i==8)
                    break;
                String imgSrc = imgList.get(i).absUrl("src");
                InputStream input = new java.net.URL(imgSrc).openStream();
                Bitmap bitmap = BitmapFactory.decodeStream(input);
                imgRealList.add(bitmap);
            }

            // I think according to your code; the data you've requested is ready
            // to deliver from now on. But attention! we post it to execute it in the UI thread
            uiHandler.post(() -> requestConsumer.onRequestResult(imgRealList));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

addItem活动类

public class addItem extends AppCompatActivity {

    LoadingDialog loadingDialog;
    RecyclerView imgList;
    ArrayList<Bitmap> bitmapList = new ArrayList<>();
    BitmapAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
       /*
       / Code Unnecessary to the problem…
       */
       et_title.setOnFocusChangeListener((v, hasFocus) -> {
            if(!hasFocus){
                getImageLogo(et_title.getText().toString());
            }
        });
    }

    @SuppressLint("NotifyDataSetChanged")
    private void getImageLogo(String serviceName){
        googleRequest googleList = new googleRequest(serviceName, images -> {
            // Here we get the delivered results in this callback
            if(images != null) {
                bitmapList.clear();
                bitmapList.addAll(images);
            }else {
                bitmapList.clear();
            }
            adapter.notifyDataSetChanged();
        });
        googleList.start();


    }
}

注意,我已经在文本编辑器中编写了它,因此代码需要一些功能测试。

 类似资料:
  • 我有一个在Tomcat7上运行的Spring3.0WebMVC应用程序。在应用程序启动时,我启动一个后台线程来加载内存缓存,其中包含来自数据库的记录。该线程从数据库加载所有数据通常需要一个多小时。在同一个应用程序中,我有一个@Controller注释类,它公开了一个REST接口,客户端可以通过该接口从加载的缓存中获取对象。 我们的要求之一是,在数据加载完成之前发出的任何REST请求都将立即向客户端

  • 我想让一些代码在后台持续运行。我不想在服务中这样做。还有其他可能的方法吗? 我曾尝试在我的活动中调用线程类,但我的活动在后台保留了一段时间,然后就停止了。线程类也停止工作。

  • 我正在开发一个Android应用程序,我必须允许用户使用相机扫描QR码。 在每个Android版本中(除外 我阅读了开发android网站的文档,但我不理解一些事情: 守则第二部分: 如何使此代码适应我的问题? 什么是“MY_PERMISSIONS_REQUEST_READ_CONTACTS”?

  • 问题内容: 我有下表,其中的表是空的,我正在尝试填充: 要填充的源数据是我从外部CSV文件填充的临时表: 我想做的是用中的值填充。该字段可以直接复制,但是我不太确定如何获取正确的内容(可以使用tmp_table.langname确定language.id)和(tmp_table.tplname,tmp_table.source,tmp_table.domain一起使用)确定template.id)

  • 问题内容: 我使用python和selenium结合使用创建了一个脚本来解析,并且打算在http请求发布后用作有效负载。当我发现很难刮,并使用要求,我想抓住他们使用selenium,这样我可以同时使一个POST请求使用它们。 我正在尝试在旁边的输入框中填充使用的结果。我可以注意到结果是通过我试图以编程方式实现的发帖请求填充的。 网站连结 要填充结果,必须依次执行此 图像中 的步骤,最终导致该图像