主頁 > .NET開發 > 從另一個片段回傳后如何防止片段重繪recyclerview/保存recyclerview位置

從另一個片段回傳后如何防止片段重繪recyclerview/保存recyclerview位置

2021-11-17 06:56:47 .NET開發

賞金過期5天回答這個問題有資格獲得 50聲望獎勵。 MML正在尋找規范的答案

在這部分中,我嘗試在我的應用程式中添加一項功能并解決一個問題,我想保存 recyclerview 位置,因此當單擊并導航到詳細資訊片段并單擊回傳時,這應該回到相同的位置,這里的問題是我點擊回傳我看到專案重疊,大約有 8 個專案,它從下一個串列位置開始,當我尋找這個問題的解決方案時,我找到了這個答案然后我決定單獨添加 recyclerview 的依賴項implementation "androidx.recyclerview:recyclerview:1.2.1"來使用這個功能

adapter.setStateRestorationPolicy(RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY);

但它不起作用,下一個GIF描述問題

recyclerview位置問題

以及具有此功能的應用程式示例

目標

首頁片段

@AndroidEntryPoint
public class HomeFragment extends Fragment {

    private FragmentHomeBinding binding;
    private PostViewModel postViewModel;
    public static final String TAG = "HomeFragment";
    private PostAdapter adapter;
    private List<Item> itemArrayList;
    private GridLayoutManager titleLayoutManager, gridLayoutManager;
    WrapContentLinearLayoutManager layoutManager;

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        binding.homeRecyclerView.addOnItemTouchListener(new RecyclerItemClickListener(requireContext(),
                binding.homeRecyclerView, new RecyclerItemClickListener.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {

                Item item = itemArrayList.get(position);

                if (Objects.requireNonNull
                        (Navigation.findNavController(requireView())
                                .getCurrentDestination()).getId() == R.id.nav_home) {
                    Navigation.findNavController(requireView())
                            .navigate(HomeFragmentDirections.actionNavHomeToDetailsFragment(item));
                }
            }

            @Override
            public void onLongItemClick(View view, int position) {

            }
        }));
    }


    public View onCreateView(@NonNull LayoutInflater inflater,
                             @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {


        binding = FragmentHomeBinding.inflate(inflater, container, false);
        setHasOptionsMenu(true);

        postViewModel = new ViewModelProvider(this).get(PostViewModel.class);
        postViewModel.finalURL.setValue(Constants.getBaseUrl()   "?key="   Constants.getKEY());
        itemArrayList = new ArrayList<>();
        adapter = new PostAdapter(getContext(), itemArrayList, this, postViewModel);

        layoutManager = new WrapContentLinearLayoutManager(requireContext(),
                LinearLayoutManager.VERTICAL, false);
        titleLayoutManager = new GridLayoutManager(getContext(), 2);
        gridLayoutManager = new GridLayoutManager(getContext(), 3);


//        binding.homeRecyclerView.setAdapter(adapter);
        binding.shimmerLayout.setVisibility(View.VISIBLE);
        binding.homeRecyclerView.setVisibility(View.INVISIBLE);

        adapter.setStateRestorationPolicy(RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY);


        postViewModel.recyclerViewLayoutMT.observe(getViewLifecycleOwner(), layout -> {
            Log.w(TAG, "getSavedLayout: called");
            switch (layout) {
                case "cardLayout":
                    binding.loadMoreBtn.setVisibility(View.VISIBLE);
                    binding.homeRecyclerView.setLayoutManager(layoutManager);
                    binding.homeRecyclerView.setAdapter(adapter);
                    adapter.setViewType(0);

                    break;
                case "cardMagazineLayout":
                    binding.loadMoreBtn.setVisibility(View.VISIBLE);
                    binding.homeRecyclerView.setLayoutManager(layoutManager);
                    binding.homeRecyclerView.setAdapter(adapter);
                    adapter.setViewType(1);
                    break;
                case "titleLayout":
                    binding.loadMoreBtn.setVisibility(View.GONE);
                    binding.homeRecyclerView.setLayoutManager(titleLayoutManager);
                    binding.homeRecyclerView.setAdapter(adapter);
                    adapter.setViewType(2);
                    break;
                case "gridLayout":
                    binding.loadMoreBtn.setVisibility(View.GONE);
                    binding.homeRecyclerView.setLayoutManager(gridLayoutManager);
                    binding.homeRecyclerView.setAdapter(adapter);
                    adapter.setViewType(3);
            }
        });


        if (Utils.hasNetworkAccess(requireContext())) {

            postViewModel.getPosts();

            postViewModel.postListMutableLiveData.observe(getViewLifecycleOwner(), postList -> {
                itemArrayList.addAll(postList.getItems());
                binding.shimmerLayout.stopShimmer();
                binding.shimmerLayout.setVisibility(View.GONE);
                binding.homeRecyclerView.setVisibility(View.VISIBLE);
                adapter.notifyDataSetChanged();

                Log.e(TAG, "ItemsArrayList :"   itemArrayList.get(0).getTitle());

            });


        } else {

            binding.shimmerLayout.setVisibility(View.VISIBLE);
//            binding.shimmerLayout.startShimmer();


            if (postViewModel.getAllItemsFromDataBase == null) {

                noInternetConnectionLayout();

            } else {
//                Log.e(TAG, "RoomDB Items size :"   itemsDatabase.itemDAO().getAlItems());

                binding.shimmerLayout.stopShimmer();
                binding.shimmerLayout.setVisibility(View.GONE);
                binding.emptyView.setVisibility(View.GONE);
                binding.homeRecyclerView.setVisibility(View.VISIBLE);
                postViewModel.getAllItemsFromDataBase.observe(getViewLifecycleOwner(), items -> {
                    if (items.isEmpty()) {
                        noInternetConnectionLayout();
                    } else {
                        binding.loadMoreBtn.setVisibility(View.GONE);
                        itemArrayList.addAll(items);
                        adapter.notifyDataSetChanged();
                    }
                });

            }
        }

        postViewModel.errorCode.observe(getViewLifecycleOwner(), errorCode -> {
            if (errorCode == 400) {
                Snackbar.make(requireView(), R.string.lastPost, Snackbar.LENGTH_LONG).show();
            } else {
                binding.homeRecyclerView.setVisibility(View.INVISIBLE);
                binding.emptyView.setVisibility(View.VISIBLE);
            }
        });

        binding.loadMoreBtn.setOnClickListener(view -> {
            AlertDialog dialog = Utils.setProgressDialog(requireContext());

            postViewModel.isLoading.observe(getViewLifecycleOwner(), isLoading -> {
                if (isLoading) {
                    dialog.show();
                } else {
                    dialog.dismiss();
                }
            });

            if (Utils.hasNetworkAccess(requireContext())) {
                postViewModel.getPosts();
//                Log.w(TAG, "loadMoreBtn: "   dialog.isShowing());
            } else {
                postViewModel.isLoading.postValue(true);
                postViewModel.getAllItemsFromDataBase.getValue();
                postViewModel.isLoading.postValue(false);
            }

        });

        return binding.getRoot();

    }

    private void noInternetConnectionLayout() {
        binding.shimmerLayout.stopShimmer();
        binding.shimmerLayout.setVisibility(View.GONE);
        binding.homeRecyclerView.setVisibility(View.GONE);
        binding.emptyView.setVisibility(View.VISIBLE);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        itemArrayList.clear();
        binding = null;
    }


    @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {

        inflater.inflate(R.menu.main, menu);
        super.onCreateOptionsMenu(menu, inflater);

        SearchManager searchManager = (SearchManager) requireContext().getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView = (SearchView) menu.findItem(R.id.app_bar_search).getActionView();
        searchView.setSearchableInfo(searchManager.getSearchableInfo(requireActivity().getComponentName()));
        searchView.setQueryHint(getResources().getString(R.string.searchForPosts));

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String keyword) {
                if (keyword.isEmpty()) {
                    Snackbar.make(requireView(), "please enter keyword to search", Snackbar.LENGTH_SHORT).show();
                }
                if (Utils.hasNetworkAccess(requireContext())) {
                    itemArrayList.clear();
                    postViewModel.getItemsBySearch(keyword);
                    adapter.notifyDataSetChanged();
                } else {
                    postViewModel.getItemsBySearchInDB(keyword);
                    postViewModel.getItemsBySearchMT.observe(getViewLifecycleOwner(), items ->
                            {
                                Log.d(TAG, "onQueryTextSubmit database called");
                                itemArrayList.clear();
                                itemArrayList.addAll(items);
                                adapter.notifyDataSetChanged();
                            }
                    );
                }
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                return false;
            }
        });


        searchView.setOnCloseListener(() -> {

            if (Utils.hasNetworkAccess(requireContext())) {
                Log.d(TAG, "setOnCloseListener: called");
                itemArrayList.clear();
                binding.emptyView.setVisibility(View.GONE);
                binding.homeRecyclerView.setVisibility(View.VISIBLE);
                postViewModel.getPosts();
                adapter.notifyDataSetChanged();
            } else {
                Log.d(TAG, "setOnCloseListener: called");
                binding.emptyView.setVisibility(View.GONE);
                binding.homeRecyclerView.setVisibility(View.VISIBLE);
                postViewModel.getAllItemsFromDataBase.observe(getViewLifecycleOwner(), items ->
                        {
                            itemArrayList.addAll(items);
                            adapter.notifyDataSetChanged();
                        }
                );
            }
            return false;
        });


        postViewModel.searchError.observe(getViewLifecycleOwner(), searchError -> {
            if (searchError) {
                Toast.makeText(requireContext(),
                        "There's no posts with this keyword", Toast.LENGTH_LONG).show();
            }
        });


    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {

        if (item.getItemId() == R.id.change_layout) {
            changeAndSaveLayout();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

視圖模型

@HiltViewModel
public class PostViewModel extends ViewModel {

    public static final String TAG = "PostViewModel";


    private final com.blogspot.abtallaldigital.data.Repository repository;
    public final MutableLiveData<PostList> postListMutableLiveData = new MutableLiveData<>();
    public final MutableLiveData<String> finalURL = new MutableLiveData<>();
    public final MutableLiveData<String> token = new MutableLiveData<>();
    public final MutableLiveData<String> label = new MutableLiveData<>();
    public final MutableLiveData<Integer> errorCode = new MutableLiveData<>();
    public final MutableLiveData<Boolean> searchError = new MutableLiveData<>();
    public final LiveData<List<Item>> getAllItemsFromDataBase;
    public final MutableLiveData<List<Item>>
            getItemsBySearchMT = new MutableLiveData<>();
    public final MutableLiveData<Boolean> isLoading = new MutableLiveData<>();
    public final MutableLiveData<String> recyclerViewLayoutMT = new MutableLiveData<>();
    private final Utils.DataStoreRepository dataStoreRepository;
    public final MutableLiveData<Integer> currentDestination = new MutableLiveData<>();


//    public MutableLiveData<Boolean> ifAnythingWrongHappened = new MutableLiveData<>();

    @Inject
    public PostViewModel(Repository repository, Utils.DataStoreRepository dataStoreRepository) {
        this.repository = repository;
        getAllItemsFromDataBase = repository.localDataSource.getAllItems();
        this.dataStoreRepository = dataStoreRepository;
        dataStoreRepository.readLayoutFlow
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new FlowableSubscriber<String>() {
                    @Override
                    public void onSubscribe(@NonNull Subscription s) {
                        s.request(Long.MAX_VALUE);
                    }

                    @Override
                    public void onNext(String layout) {
                        if (layout != null) {
                            recyclerViewLayoutMT.setValue(layout);
                        }
                    }

                    @Override
                    public void onError(Throwable t) {
                        Log.e(TAG, "onError: "   t.getMessage());
                        Log.e(TAG, "onError: "   t.getCause());
                    }

                    @Override
                    public void onComplete() {

                    }
                });

        dataStoreRepository.readCurrentDestination
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .firstOrError().subscribeWith(new SingleObserver<Integer>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {

            }

            @Override
            public void onSuccess(@NonNull Integer destination) {
                currentDestination.setValue(destination);
            }

            @Override
            public void onError(@NonNull Throwable e) {
                Log.e(TAG, "onError: "   e.getMessage());
            }
        });

    }

    public void saveRecyclerViewLayout(String layout) {
        dataStoreRepository.saveRecyclerViewLayout("recyclerViewLayout", layout);
    }

    public void saveCurrentDestination(int currentDestination) {
        dataStoreRepository
                .saveCurrentDestination("CURRENT_DESTINATION", currentDestination);
    }


    //    @Override
//    protected void onCleared() {
//        super.onCleared();
//        postListMutableLiveData.setValue(null);
//        finalURL.setValue(null);
//        token.setValue(null);
//    }

    public void getPosts() {
        Log.e(TAG, finalURL.getValue());

        isLoading.setValue(true);
        repository.remoteDataSource.getPostList(finalURL.getValue())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Response<PostList>>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {

                    }

                    @Override
                    public void onNext(@NonNull Response<PostList> postListResponse) {

                        if (postListResponse.isSuccessful()) {
                            if (postListResponse.body() != null
                                    && postListResponse.body().getNextPageToken() != null) {
                                Log.e(TAG, postListResponse.body().getNextPageToken());
                                token.setValue(postListResponse.body().getNextPageToken());
                                isLoading.setValue(false);
                            }
                            postListMutableLiveData.setValue(postListResponse.body());

                            for (int i = 0; i < postListResponse.body().getItems().size(); i  ) {
                                repository.localDataSource.insertItem(postListResponse.body()
                                        .getItems().get(i))
                                        .subscribeOn(Schedulers.io())
                                        .observeOn(AndroidSchedulers.mainThread())
                                        .subscribe(new CompletableObserver() {
                                            @Override
                                            public void onSubscribe(@NonNull Disposable d) {

                                            }

                                            @Override
                                            public void onComplete() {

                                            }

                                            @Override
                                            public void onError(@NonNull Throwable e) {

                                            }
                                        });
                            }

                            finalURL.setValue(finalURL.getValue()   "&pageToken="   token.getValue());
                        } else {
                            isLoading.setValue(false);
                            errorCode.setValue(postListResponse.code());
                            Log.e(TAG, "onNext: "   postListResponse.code());
                            Log.e(TAG, "onNext: "   postListResponse.errorBody());
                        }
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        isLoading.setValue(false);
                        Log.e(TAG, e.getMessage()   e.getCause());
//                        ifAnythingWrongHappened.setValue(true);
                        if (e instanceof HttpException) {
                            errorCode.setValue(((HttpException) e).code());
                        }
                    }

                    @Override
                    public void onComplete() {

                    }
                });

    }


    public void getPostListByLabel() {

        isLoading.setValue(true);
        Log.e(TAG, finalURL.getValue());

        repository.remoteDataSource.getPostListByLabel(finalURL.getValue())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Response<com.blogspot.abtallaldigital.pojo.PostList>>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {

                    }

                    @Override
                    public void onNext(@NonNull Response<com.blogspot.abtallaldigital.pojo.PostList> postListResponse) {
                        if (postListResponse.isSuccessful()) {
                            if (postListResponse.body() != null) {
//                                Log.e(TAG, postListResponse.body().getNextPageToken());
                                token.setValue(postListResponse.body().getNextPageToken());
                            }
                            postListMutableLiveData.setValue(postListResponse.body());
                            isLoading.setValue(false);
                            finalURL.postValue(Constants.getBaseUrlPostsByLabel()
                                      "posts?labels="   label.getValue()   "&pageToken="
                                      token.getValue()
                                      "&key="   Constants.getKEY());
                        } else {
                            isLoading.setValue(false);
                            errorCode.setValue(postListResponse.code());
                            Log.e(TAG, "onNext: "   postListResponse.code());
                            Log.e(TAG, "onNext: "   postListResponse.errorBody());
                        }
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        isLoading.setValue(false);
                        Log.e(TAG, e.getMessage()   e.getCause());
                        if (e instanceof HttpException) {
                            errorCode.setValue(((HttpException) e).code());
                        }
                    }

                    @Override
                    public void onComplete() {

                    }
                });

    }

    public void getItemsBySearch(String keyword) {

        isLoading.setValue(true);
        searchError.setValue(false);

        String url = Constants.getBaseUrl()  
                "search?q="   keyword   "&key="   Constants.getKEY();

        Log.e(TAG, "getItemsBySearch: "   url);

        repository.remoteDataSource.getPostListBySearch(url)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Response<com.blogspot.abtallaldigital.pojo.PostList>>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {

                    }

                    @Override
                    public void onNext(@NonNull Response<PostList> postListResponse) {

                        if (postListResponse.isSuccessful()) {
                            if (postListResponse.body() != null
                                    && postListResponse.body().getNextPageToken() != null) {
                                Log.e(TAG, postListResponse.body().getNextPageToken());
                                token.setValue(postListResponse.body().getNextPageToken());
                                isLoading.setValue(false);
                            }
                            postListMutableLiveData.setValue(postListResponse.body());
                        } else {
                            isLoading.setValue(false);
                            searchError.setValue(true);
                            Log.e(TAG, "onNext: list is null");
                        }
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        isLoading.setValue(false);
                        Log.e(TAG, e.getMessage()   e.getCause());
//                        ifAnythingWrongHappened.setValue(true);
                        if (e instanceof HttpException) {
                            errorCode.setValue(((HttpException) e).code());
                        }
                    }

                    @Override
                    public void onComplete() {

                    }
                });

    }

    public void getItemsBySearchInDB(String keyword) {
        Log.d(TAG, "getItemsBySearchInDB: called");
        repository.localDataSource.getItemsBySearch(keyword)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<List<com.blogspot.abtallaldigital.pojo.Item>>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {

                    }

                    @Override
                    public void onNext(@NonNull List<Item> items) {
                        if (items.isEmpty()) {
                            searchError.setValue(true);
                            Log.e(TAG, "onNext: list is empty");
                        } else {
                            getItemsBySearchMT.setValue(items);
                            Log.d(TAG, "onNext: "   items.size());
                        }
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        searchError.setValue(true);
                    }

                    @Override
                    public void onComplete() {

                    }
                });

    }

    public void insertFavorites(FavoritesEntity favoritesEntity) {
        repository.localDataSource.insertFavorites(favoritesEntity)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new CompletableObserver() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {

                    }

                    @Override
                    public void onComplete() {

                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.e(TAG, "onError: "   e.getMessage());
                    }
                });
    }

    public LiveData<List<FavoritesEntity>> getAllFavorites() {
        return repository.localDataSource.getAllFavorites();
    }

    public void deleteFavoritePost(FavoritesEntity favoritesEntity) {
        repository.localDataSource.deleteFavorite(favoritesEntity);
    }

    public void deleteAllFavorites() {
        repository.localDataSource.deleteAllFavorites()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new CompletableObserver() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {

                    }

                    @Override
                    public void onComplete() {

                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.e(TAG, "onError: "   e.getMessage());
                    }
                });


    }


}

uj5u.com熱心網友回復:

嘗試在onCreate而不是初始化配接器onViewCreated 然后您可以在 recyclerview 中設定配接器onViewCreated

還可以嘗試使用 LiveData 事件包裝器:https ://stackoverflow.com/a/51762972/9854554

Java 中的 LiveData 事件包裝器:https ://stackoverflow.com/a/56072658

它會阻止 livedata 觀察者在片段恢復時再次獲取資料(當我們再次訂閱 livedata 時)

uj5u.com熱心網友回復:

您在設定回收視圖資料onViewCreated,要求每次,我建議視圖模型更好的生命周期移交,使用LiveDataStateflow中的視圖模型來證明你的資料的完整性

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/357964.html

標籤:爪哇 安卓 android-fragments android-recyclerview 安卓导航

上一篇:如何制作一個將Activity和Fragment作為引數背景關系的函式

下一篇:如何根據Kotlin中選擇的片段顯示/隱藏FloatingActionButton?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more